gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/Makefile.am server/named...


From: Chad Musick
Subject: [Gnash-commit] gnash ChangeLog server/Makefile.am server/named...
Date: Sat, 29 Sep 2007 08:24:22 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Chad Musick <cmusick>   07/09/29 08:24:22

Modified files:
        .              : ChangeLog 
        server         : Makefile.am namedStrings.cpp namedStrings.h 
        server/asobj   : ClassHierarchy.cpp ClassHierarchy.h Global.cpp 
        server/parser  : Namespace.h abc_block.cpp abc_block.h 
        server/vm      : VM.cpp 
        testsuite/samples: .cvsignore 
Added files:
        extensions/dbus: .cvsignore 
        extensions/lirc: .cvsignore 
        libmedia       : .cvsignore 
        server         : asClass.cpp asClass.h 

Log message:
        Add some .cvsignore files
        
        New type library system for (so far) ActionScript 3.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4472&r2=1.4473
http://cvs.savannah.gnu.org/viewcvs/gnash/extensions/dbus/.cvsignore?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/extensions/lirc/.cvsignore?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/libmedia/.cvsignore?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/Makefile.am?cvsroot=gnash&r1=1.126&r2=1.127
http://cvs.savannah.gnu.org/viewcvs/gnash/server/namedStrings.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/namedStrings.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asClass.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asClass.h?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/ClassHierarchy.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/ClassHierarchy.h?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Global.cpp?cvsroot=gnash&r1=1.71&r2=1.72
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/Namespace.h?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/abc_block.cpp?cvsroot=gnash&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/gnash/server/parser/abc_block.h?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/VM.cpp?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/samples/.cvsignore?cvsroot=gnash&r1=1.6&r2=1.7

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4472
retrieving revision 1.4473
diff -u -b -r1.4472 -r1.4473
--- ChangeLog   29 Sep 2007 06:33:25 -0000      1.4472
+++ ChangeLog   29 Sep 2007 08:24:20 -0000      1.4473
@@ -1,3 +1,22 @@
+2007-09-29 Chad Musick <address@hidden>
+
+       * New: server/asClass.h,.cpp: Several different classes which work
+         together to construct a type library for ActionScript 3.  Work is
+         in progress to make this glean the same information from the current
+         ActionScript 2 information (through the Global object, as well
+         as hand coding) so that the 'implements' op can be written and so
+         that various AS2 things will work better.  This is not yet complete.
+         Because this code is in flux (though currently not broken), it is
+         not yet extensively commented.
+       * server/Makefile.am: Add new files
+       * server/namedStrings.h,.cpp: New strings for the AS3 namespaces.
+       * server/parser/Namespace.h: Add resource marking -- this file is
+         going to be obsolete as soon as dependencies are verified.
+       * server/parser/abc_block.h,.cpp: Update to be more modular, and to
+         build a type library from AS3 tag.
+       * server/vm/VM.cpp: Change to registration method for new types.
+       * New: Various .cvsignore files
+
 2007-09-29 Sandro Santilli <address@hidden>
 
        * testsuite/misc-swfc.all/: Dejagnu.sc, check.sc,

Index: server/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/server/Makefile.am,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -b -r1.126 -r1.127
--- server/Makefile.am  27 Sep 2007 23:59:55 -0000      1.126
+++ server/Makefile.am  29 Sep 2007 08:24:21 -0000      1.127
@@ -18,7 +18,7 @@
 # 
 #
 
-# $Id: Makefile.am,v 1.126 2007/09/27 23:59:55 tgc Exp $
+# $Id: Makefile.am,v 1.127 2007/09/29 08:24:21 cmusick Exp $
 
 AUTOMAKE_OPTIONS = 
 
@@ -65,6 +65,7 @@
        as_function.cpp \
        as_object.cpp \
        as_value.cpp \
+       asClass.cpp \
        character.cpp \
        cxform.cpp \
        DynamicShape.cpp        \
@@ -129,6 +130,7 @@
        as_object.h \
        as_prop_flags.h \
        as_value.h \
+       asClass.h \
        bitmap_info.h \
        BitmapMovieInstance.h \
        builtin_function.h \

Index: server/namedStrings.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/namedStrings.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/namedStrings.cpp     23 Sep 2007 22:33:56 -0000      1.2
+++ server/namedStrings.cpp     29 Sep 2007 08:24:21 -0000      1.3
@@ -125,6 +125,18 @@
        { "ContextMenu", NSV::CLASS_CONTEXT_MENU },
        { "MovieClipLoader", NSV::CLASS_MOVIE_CLIP_LOADER },
        { "Error", NSV::CLASS_ERROR },
+       { "flash.display", NSV::NS_FLASH_DISPLAY },
+       { "flash.text", NSV::NS_FLASH_TEXT },
+       { "flash.geom", NSV::NS_FLASH_GEOM },
+       { "flash.net", NSV::NS_FLASH_NET },
+       { "flash.system", NSV::NS_FLASH_SYSTEM },
+       { "flash.utils", NSV::NS_FLASH_UTILS },
+       { "flash.events", NSV::NS_FLASH_EVENTS },
+       { "flash.accessibility", NSV::NS_FLASH_ACCESSIBILITY },
+       { "flash.media", NSV::NS_FLASH_MEDIA },
+       { "flash.xml", NSV::NS_FLASH_XML },
+       { "flash.ui", NSV::NS_FLASH_UI },
+       { "adobe.utils", NSV::NS_ADOBE_UTILS },
 };
 
 void load_strings(string_table *table, int version)

Index: server/namedStrings.h
===================================================================
RCS file: /sources/gnash/gnash/server/namedStrings.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/namedStrings.h       23 Sep 2007 22:46:30 -0000      1.4
+++ server/namedStrings.h       29 Sep 2007 08:24:21 -0000      1.5
@@ -142,7 +142,19 @@
                CLASS_NET_STREAM,
                CLASS_CONTEXT_MENU,
                CLASS_MOVIE_CLIP_LOADER,
-               CLASS_ERROR
+               CLASS_ERROR,
+               NS_FLASH_DISPLAY,
+               NS_FLASH_TEXT,
+               NS_FLASH_GEOM,
+               NS_FLASH_NET,
+               NS_FLASH_SYSTEM,
+               NS_FLASH_UTILS,
+               NS_FLASH_EVENTS,
+               NS_FLASH_ACCESSIBILITY,
+               NS_FLASH_MEDIA,
+               NS_FLASH_XML,
+               NS_FLASH_UI,
+               NS_ADOBE_UTILS
        } named_strings;
 
 /// Load the prenamed strings.

Index: server/asobj/ClassHierarchy.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/ClassHierarchy.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/asobj/ClassHierarchy.cpp     24 Sep 2007 15:39:31 -0000      1.2
+++ server/asobj/ClassHierarchy.cpp     29 Sep 2007 08:24:21 -0000      1.3
@@ -63,6 +63,7 @@
 #include "xmlsocket.h"
 #include "xml.h"
 #include "xmlnode.h"
+#include "asClass.h"
 
 namespace gnash {
 
@@ -189,7 +190,9 @@
        if (mExtension == NULL)
                return false; // Extensions can't be loaded.
 
-       mGlobalNamespace.stubPrototype(c.name);
+       mGlobalNamespace->stubPrototype(c.name);
+       mGlobalNamespace->getClass(c.name)->setDeclared();
+       mGlobalNamespace->getClass(c.name)->setSystem();
 
        boost::intrusive_ptr<as_function> getter =
                new declare_extension_function(c, mGlobal, mExtension);
@@ -203,7 +206,14 @@
 bool
 ClassHierarchy::declareClass(nativeClass& c)
 {
-       mGlobalNamespace.stubPrototype(c.name);
+       // For AS2 and below, registering with mGlobal _should_ make it 
equivalent
+       // to being in the global namespace, since everything is global there.
+       asNamespace *nso = findNamespace(c.namespace_name);
+       if (!nso)
+               nso = addNamespace(c.namespace_name);
+       nso->stubPrototype(c.name);
+       nso->getClass(c.name)->setDeclared();
+       nso->getClass(c.name)->setSystem();
 
        boost::intrusive_ptr<as_function> getter =
                new declare_native_function(c, mGlobal, mExtension);
@@ -216,40 +226,45 @@
 
 static ClassHierarchy::nativeClass knownClasses[] =
 {
+// This makes it clear the difference between "We don't know where the
+// class belongs" and "it belongs in the global namespace", even though
+// the result is the same.
+#define NS_GLOBAL 0
+#define NS_UNKNOWN 0
        /* { function_name, name key, super name key, lowest version }, */
-//     { object_class_init, NSV::CLASS_OBJECT, 0, 5 }, // Object is special
-//     { function_class_init, NSV::CLASS_FUNCTION, NSV::CLASS_OBJECT, 6 }, // 
Function is special
-//     { array_class_init, NSV::CLASS_ARRAY, NSV::CLASS_OBJECT, 5 }, // Array 
is special
-       { system_class_init, NSV::CLASS_SYSTEM, 0, 1 },
-       { stage_class_init, NSV::CLASS_STAGE, 0, 1 },
-       { movieclip_class_init, NSV::CLASS_MOVIE_CLIP, 0, 3 },
-       { textfield_class_init, NSV::CLASS_TEXT_FIELD, 0, 3 },
-       { math_class_init, NSV::CLASS_MATH, 0, 4 },
-       { boolean_class_init, NSV::CLASS_BOOLEAN, NSV::CLASS_OBJECT, 5 },
-       { color_class_init, NSV::CLASS_COLOR, NSV::CLASS_OBJECT, 5 },
-       { selection_class_init, NSV::CLASS_SELECTION, NSV::CLASS_OBJECT, 5 },
-       { sound_class_init, NSV::CLASS_SOUND, NSV::CLASS_OBJECT, 5 },
-       { xmlsocket_class_init, NSV::CLASS_X_M_L_SOCKET, NSV::CLASS_OBJECT, 5 },
-       { date_class_init, NSV::CLASS_DATE, NSV::CLASS_OBJECT, 5 },
-       { xml_class_init, NSV::CLASS_X_M_L, NSV::CLASS_OBJECT, 5 },
-       { xmlnode_class_init, NSV::CLASS_X_M_L_NODE, NSV::CLASS_OBJECT, 5 },
-       { mouse_class_init, NSV::CLASS_MOUSE, NSV::CLASS_OBJECT, 5 },
-       { number_class_init, NSV::CLASS_NUMBER, NSV::CLASS_OBJECT, 5 },
-       { string_class_init, NSV::CLASS_STRING, NSV::CLASS_OBJECT, 5 },
-       { key_class_init, NSV::CLASS_KEY, NSV::CLASS_OBJECT, 5 },
-       { AsBroadcaster_init, NSV::CLASS_AS_BROADCASTER, NSV::CLASS_OBJECT, 5 },
-       { textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT, NSV::CLASS_OBJECT, 
6 },
-       { video_class_init, NSV::CLASS_VIDEO, NSV::CLASS_OBJECT, 6 },
-       { camera_class_init, NSV::CLASS_CAMERA, NSV::CLASS_OBJECT, 6 },
-       { microphone_class_init, NSV::CLASS_MICROPHONE, NSV::CLASS_OBJECT, 6 },
-       { sharedobject_class_init, NSV::CLASS_SHARED_OBJECT, NSV::CLASS_OBJECT, 
6 },
-       { loadvars_class_init, NSV::CLASS_LOAD_VARS, NSV::CLASS_OBJECT, 6 },
-       { customactions_class_init, NSV::CLASS_CUSTOM_ACTIONS, 
NSV::CLASS_OBJECT, 6 },
-       { netconnection_class_init, NSV::CLASS_NET_CONNECTION, 
NSV::CLASS_OBJECT, 7 },
-       { netstream_class_init, NSV::CLASS_NET_STREAM, NSV::CLASS_OBJECT, 7 },
-       { contextmenu_class_init, NSV::CLASS_CONTEXT_MENU, NSV::CLASS_OBJECT, 7 
},
-       { moviecliploader_class_init, NSV::CLASS_MOVIE_CLIP_LOADER, 
NSV::CLASS_OBJECT, 7 },
-       { error_class_init, NSV::CLASS_ERROR, NSV::CLASS_OBJECT, 7 },
+//     { object_class_init, NSV::CLASS_OBJECT, 0, NS_GLOBAL, 5 }, // Object is 
special
+//     { function_class_init, NSV::CLASS_FUNCTION, NSV::CLASS_OBJECT, 
NS_GLOBAL, 6 }, // Function is special
+//     { array_class_init, NSV::CLASS_ARRAY, NSV::CLASS_OBJECT, NS_GLOBAL, 5 
}, // Array is special
+       { system_class_init, NSV::CLASS_SYSTEM, 0, NSV::NS_FLASH_SYSTEM, 1 },
+       { stage_class_init, NSV::CLASS_STAGE, 0, NSV::NS_FLASH_DISPLAY, 1 },
+       { movieclip_class_init, NSV::CLASS_MOVIE_CLIP, 0, 
NSV::NS_FLASH_DISPLAY, 3 },
+       { textfield_class_init, NSV::CLASS_TEXT_FIELD, 0, NSV::NS_FLASH_TEXT, 3 
},
+       { math_class_init, NSV::CLASS_MATH, 0, NS_GLOBAL, 4 },
+       { boolean_class_init, NSV::CLASS_BOOLEAN, NSV::CLASS_OBJECT, NS_GLOBAL, 
5 },
+       { color_class_init, NSV::CLASS_COLOR, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
+       { selection_class_init, NSV::CLASS_SELECTION, NSV::CLASS_OBJECT, 
NS_UNKNOWN, 5 },
+       { sound_class_init, NSV::CLASS_SOUND, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_MEDIA, 5 },
+       { xmlsocket_class_init, NSV::CLASS_X_M_L_SOCKET, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_NET, 5 },
+       { date_class_init, NSV::CLASS_DATE, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
+       { xml_class_init, NSV::CLASS_X_M_L, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
+       { xmlnode_class_init, NSV::CLASS_X_M_L_NODE, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_XML, 5 },
+       { mouse_class_init, NSV::CLASS_MOUSE, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_UI, 5 },
+       { number_class_init, NSV::CLASS_NUMBER, NSV::CLASS_OBJECT, NS_GLOBAL, 5 
},
+       { string_class_init, NSV::CLASS_STRING, NSV::CLASS_OBJECT, NS_GLOBAL, 5 
},
+       { key_class_init, NSV::CLASS_KEY, NSV::CLASS_OBJECT, NS_GLOBAL, 5 },
+       { AsBroadcaster_init, NSV::CLASS_AS_BROADCASTER, NSV::CLASS_OBJECT, 
NS_GLOBAL, 5 },
+       { textsnapshot_class_init, NSV::CLASS_TEXT_SNAPSHOT, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_TEXT, 6 },
+       { video_class_init, NSV::CLASS_VIDEO, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_MEDIA, 6 },
+       { camera_class_init, NSV::CLASS_CAMERA, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_UI, 6 },
+       { microphone_class_init, NSV::CLASS_MICROPHONE, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_UI, 6 },
+       { sharedobject_class_init, NSV::CLASS_SHARED_OBJECT, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_NET, 6 },
+       { loadvars_class_init, NSV::CLASS_LOAD_VARS, NSV::CLASS_OBJECT, 
NS_GLOBAL, 6 },
+       { customactions_class_init, NSV::CLASS_CUSTOM_ACTIONS, 
NSV::CLASS_OBJECT, NSV::NS_ADOBE_UTILS, 6 },
+       { netconnection_class_init, NSV::CLASS_NET_CONNECTION, 
NSV::CLASS_OBJECT, NSV::NS_FLASH_NET, 7 },
+       { netstream_class_init, NSV::CLASS_NET_STREAM, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_NET, 7 },
+       { contextmenu_class_init, NSV::CLASS_CONTEXT_MENU, NSV::CLASS_OBJECT, 
NSV::NS_FLASH_UI, 7 },
+       { moviecliploader_class_init, NSV::CLASS_MOVIE_CLIP_LOADER, 
NSV::CLASS_OBJECT, NS_GLOBAL, 7 },
+       { error_class_init, NSV::CLASS_ERROR, NSV::CLASS_OBJECT, NS_GLOBAL, 7 },
 };
 
 void
@@ -273,4 +288,22 @@
        }
 }
 
+void
+ClassHierarchy::markReachableResources() const
+{
+       // TODO
+}
+
+void
+ClassHierarchy::dump()
+{
+       namespacesContainer::iterator i;
+
+       for (i = mNamespaces.begin(); i != mNamespaces.end(); ++i)
+       {
+               (i->second).dump();
+       }
+       getGlobalNs()->dump();
+}
+
 } /* namespace gnash */

Index: server/asobj/ClassHierarchy.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/ClassHierarchy.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/asobj/ClassHierarchy.h       24 Sep 2007 15:39:31 -0000      1.2
+++ server/asobj/ClassHierarchy.h       29 Sep 2007 08:24:21 -0000      1.3
@@ -19,12 +19,64 @@
 #ifndef GNASH_CLASS_HIERARCHY_H
 #define GNASH_CLASS_HIERARCHY_H
 
+#include <list>
+#include <vector>
+
 #include "as_object.h"
-#include "Namespace.h"
+#include "asClass.h"
 
 namespace gnash {
 
 class Extension;
+class asClass;
+class asMethod;
+class asNamespace;
+class asException;
+class asMethodBody;
+class asBoundValue;
+class asBoundAccessor;
+
+template <class T> class memoryDispenser
+{
+private:
+       typedef std::vector<T> block;
+       typedef std::list<block*> blocks;
+       blocks mMemory;
+       block *mCurrent;
+       std::size_t mBlockSize;
+       std::size_t mLeftInBlock;
+
+       void grow()
+       {
+               mLeftInBlock = mBlockSize;
+               mCurrent = new block(mBlockSize);
+               mCurrent->resize(mBlockSize);
+               mMemory.push_back(mCurrent);
+       }
+
+public:
+       memoryDispenser(std::size_t allocSize) : mBlockSize(allocSize),
+               mLeftInBlock(0)
+       {/**/}
+
+       T* newMemory()
+       {
+               if (!mLeftInBlock)
+                       grow();
+               --mLeftInBlock;
+               return &(*mCurrent)[mLeftInBlock];
+       }
+
+       // Done this way because an iterator won't compile right.
+       ~memoryDispenser()
+       { 
+               while (!mMemory.empty()) 
+               {
+                       delete mMemory.front();
+                       mMemory.pop_front();
+               }
+       }
+};
 
 /// Register all of the ActionScript classes, with their dependencies.
 class ClassHierarchy
@@ -56,6 +108,10 @@
                string_table::key super_name;
 
                /// \brief
+               /// The name of the namespace in which this belongs.
+               string_table::key namespace_name;
+
+               /// \brief
                /// The version at which this should be added.
                int version;
        };
@@ -80,6 +136,10 @@
                string_table::key super_name;
 
                /// \brief
+               /// The name of the namespace in which this belongs.
+               string_table::key namespace_name;
+
+               /// \brief
                /// The version at which this should be added.
                int version;
        };
@@ -115,31 +175,45 @@
        /// Get the global namespace.  This is not the Global object -- it only
        /// contains the classes, not any globally available functions or 
anything
        /// else.
-       Namespace *getGlobalNs() { return &mGlobalNamespace; }
+       asNamespace* getGlobalNs() { return mGlobalNamespace; }
 
        /// Find a namespace with the given uri.
        ///
        /// @return 
        /// The namespace with the given uri or NULL if it doesn't exist.
-       Namespace *findNamespace(string_table::key uri)
+       asNamespace *findNamespace(string_table::key uri)
        {
-               if (uri == 0)
-                       return getGlobalNs();
-
-               std::map<string_table::key, Namespace>::iterator i;
+               namespacesContainer::iterator i;
+               if (mNamespaces.empty())
+                       return NULL;
                i = mNamespaces.find(uri);
                if (i == mNamespaces.end())
                        return NULL;
-               return &(i->second);
+               return &i->second;
        }
 
        /// \brief
+       /// Obtain a new anonymous namespace. Use this to let the object keep 
track
+       /// of all namespaces, even private ones. Namespaces obtained in this 
way
+       /// can't ever be found. (They must be kept and passed to the 
appropriate
+       /// objects.)
+       ///
+       asNamespace* anonNamespace(string_table::key uri)
+       { asNamespace* n = mAnonNamespaces.newMemory(); n->setURI(uri); return 
n; }
+
+       /// \brief
        /// Add a namespace to the set. Don't use to add unnamed namespaces.
        /// Will overwrite existing namespaces 'kind' and 'prefix' values. 
        /// Returns the added space.
-       Namespace* addNamespace(string_table::key uri, Namespace::kinds kind)
-       { Namespace &n = mNamespaces[uri]; n.initialize(uri, 0, kind);
-         return &mNamespaces[uri];}
+       asNamespace* addNamespace(string_table::key uri)
+       {
+               asNamespace *n = findNamespace(uri);
+               if (n)
+                       return n;
+               mNamespaces[uri] = asNamespace();
+               mNamespaces[uri].setURI(uri);
+               return &mNamespaces[uri];
+       }
 
        /// Set the extension object, since it wasn't set on construction.
        void setExtension(Extension *e) { mExtension = e; }
@@ -147,19 +221,61 @@
        /// Set the global object, for registrations.
        void setGlobal(as_object *g) { mGlobal = g; }
 
+       /// Mark objects for garbage collector.
+       void markReachableResources() const;
+
+       /// Create a new asClass object for use.
+       asClass *newClass()
+       { return mClassMemory.newMemory(); }
+
+       asException *newException()
+       { return mExceptionMemory.newMemory(); }
+
+       /// Create a new asMethod object for use.
+       asMethod *newMethod()
+       { return mMethodMemory.newMemory(); }
+
+       /// Create a new asMethodBody
+       asMethodBody *newMethodBody()
+       { return mMethodBodyMemory.newMemory(); }
+
+       asBoundValue *newBoundValue()
+       { return mBoundValueMemory.newMemory(); }
+
+       asBoundAccessor *newBoundAccessor()
+       { return mBoundAccessorMemory.newMemory(); }
+
        /// \brief
        /// Construct the declaration object. Later set the global and
        /// extension objects using setGlobal and setExtension
        ClassHierarchy() :
-               mGlobal(NULL), mGlobalNamespace(), mExtension(NULL)
-       {/**/}
+               mGlobal(NULL), mGlobalNamespace(NULL), mExtension(NULL),
+               mAnonNamespaces(100),
+               mClassMemory(100), mExceptionMemory(100),
+               mMethodMemory(100), mMethodBodyMemory(100),
+               mBoundValueMemory(100), mBoundAccessorMemory(100)
+       { mGlobalNamespace = anonNamespace(0); }
+
+       /// \brief
+       /// Delete our private namespaces.
+       ~ClassHierarchy();
+
+       void dump();
 
 private:
        as_object *mGlobal;
-       Namespace mGlobalNamespace;
+       asNamespace *mGlobalNamespace;
        Extension *mExtension;
 
-       std::map<string_table::key, Namespace> mNamespaces;
+       typedef std::map<string_table::key, asNamespace> namespacesContainer;
+       namespacesContainer mNamespaces;
+       memoryDispenser<asNamespace> mAnonNamespaces;
+       memoryDispenser<asClass> mClassMemory;
+       memoryDispenser<asException> mExceptionMemory;
+       memoryDispenser<asMethod> mMethodMemory;
+       memoryDispenser<asMethodBody> mMethodBodyMemory;
+       memoryDispenser<asBoundValue> mBoundValueMemory;
+       memoryDispenser<asBoundAccessor> mBoundAccessorMemory;
 };
 
 } /* namespace gnash */

Index: server/asobj/Global.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Global.cpp,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -b -r1.71 -r1.72
--- server/asobj/Global.cpp     27 Sep 2007 15:42:11 -0000      1.71
+++ server/asobj/Global.cpp     29 Sep 2007 08:24:21 -0000      1.72
@@ -17,7 +17,7 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-/* $Id: Global.cpp,v 1.71 2007/09/27 15:42:11 strk Exp $ */
+/* $Id: Global.cpp,v 1.72 2007/09/29 08:24:21 cmusick Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -404,13 +404,16 @@
        {
                object_class_init(*this);
                ch->getGlobalNs()->stubPrototype(NSV::CLASS_OBJECT);
+               ch->getGlobalNs()->getClass(NSV::CLASS_OBJECT)->setDeclared();
                array_class_init(*this);
                ch->getGlobalNs()->stubPrototype(NSV::CLASS_ARRAY);
+               ch->getGlobalNs()->getClass(NSV::CLASS_ARRAY)->setDeclared();
        }
        if (vm.getSWFVersion() >= 6)
        {
                function_class_init(*this);
                ch->getGlobalNs()->stubPrototype(NSV::CLASS_FUNCTION);
+               ch->getGlobalNs()->getClass(NSV::CLASS_FUNCTION)->setDeclared();
        }
        
        if ( vm.getSWFVersion() < 3 ) goto extscan;

Index: server/parser/Namespace.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/Namespace.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/parser/Namespace.h   24 Sep 2007 15:39:31 -0000      1.2
+++ server/parser/Namespace.h   29 Sep 2007 08:24:21 -0000      1.3
@@ -27,11 +27,11 @@
 
 #include <map>
 #include "string_table.h"
+#include "as_object.h"
 
 namespace gnash {
 
 class abc_block;
-class as_object;
 
 /// A namespace for ActionScript. Not really functional in AS2.
 ///
@@ -166,6 +166,10 @@
                return i->second;
        }
 
+       /// \brief
+       /// Mark reachable resources for GC.
+       void markReachableResources() const;
+
 private:
        string_table::key mUri;
        string_table::key mPrefix;
@@ -174,5 +178,18 @@
        std::map<string_table::key, as_object*> mMembers;
 };
 
+inline void
+Namespace::markReachableResources() const
+{
+       std::map<string_table::key, as_object*>::const_iterator i =
+               mMembers.begin();
+
+       for ( ; i != mMembers.end(); ++i)
+       {
+               if (i->second != NULL)
+                       i->second->setReachable();
+       }
+}
+
 }; /* namespace gnash */
 #endif /* GNASH_NAMESPACE_H */

Index: server/parser/abc_block.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/parser/abc_block.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- server/parser/abc_block.cpp 24 Sep 2007 15:39:31 -0000      1.6
+++ server/parser/abc_block.cpp 29 Sep 2007 08:24:21 -0000      1.7
@@ -23,18 +23,156 @@
 #include "VM.h"
 #include "log.h"
 #include "ClassHierarchy.h"
+#include "asClass.h"
+#include "namedStrings.h"
 
-#define ERR(x) IF_VERBOSE_MALFORMED_SWF(log_swferror x;);
-//#define ERR(x) printf x
+//#define ERR(x) IF_VERBOSE_MALFORMED_SWF(log_swferror x;);
+#define ERR(x) printf x; fflush(stdout);
 
 namespace gnash {
 
 namespace abc_parsing {
 
 bool
-abc_Trait::read(stream* in)
+abc_Trait::finalize(abc_block *pBlock, asClass *pClass, bool do_static)
 {
-       mNameIndex = in->read_V32();
+       switch (mKind)
+       {
+       case KIND_SLOT:
+       case KIND_CONST:
+       {
+               // Validate the type.
+               asClass *pType;
+               if (mTypeIndex)
+                       pType = 
pBlock->locateClass(pBlock->mMultinamePool[mTypeIndex]);
+               else
+                       pType = pBlock->mTheObject;
+               if (!pType)
+               {
+                       ERR((_("ABC: Finalizing trait yielded bad type for 
slot.\n")));
+                       return false;
+               }
+               // The name has been validated in read.
+               if (mHasValue)
+                       pClass->addValue(mName, mNamespace, mSlotId, pType, 
+                               mValue, mKind == KIND_CONST, do_static, 
pBlock->mCH);
+               else
+                       pClass->addSlot(mName, mNamespace, mSlotId, pType,
+                               do_static, pBlock->mCH);
+               break;
+       }
+       case KIND_METHOD:
+       {
+               pClass->addMethod(mName, mNamespace, mMethod, do_static);
+               break;
+       }
+       case KIND_GETTER:
+       {
+               pClass->addGetter(mName, mNamespace, mMethod, do_static, 
pBlock->mCH);
+               break;
+       }
+       case KIND_SETTER:
+       {
+               pClass->addSetter(mName, mNamespace, mMethod, do_static, 
pBlock->mCH);
+               break;
+       }
+       case KIND_CLASS:
+       {
+               pClass->addMemberClass(mName, mNamespace, mSlotId,
+                       pBlock->mClasses[mClassInfoIndex], do_static);
+               break;
+       }
+       case KIND_FUNCTION:
+       {
+               pClass->addSlotFunction(mName, mNamespace, mSlotId, mMethod, 
do_static);
+               break;
+       }
+       default:
+               // Not here -- validated already in read.
+               return false;
+               break;
+       } // end of switch
+       return true;
+}
+
+bool
+abc_Trait::finalize_mbody(abc_block *pBlock, asMethod *pMethod)
+{
+       switch (mKind)
+       {
+       case KIND_SLOT:
+       case KIND_CONST:
+       {
+               // Validate the type.
+               asClass *pType;
+               if (mTypeIndex)
+                       pType = 
pBlock->locateClass(pBlock->mMultinamePool[mTypeIndex]);
+               else
+                       pType = pBlock->mTheObject;
+               if (!pType)
+               {
+                       ERR((_("ABC: Finalizing trait yielded bad type for 
slot.\n")));
+                       return false;
+               }
+               // The name has been validated in read.
+               if (mHasValue)
+                       pMethod->addValue(mName, mNamespace, mSlotId, pType, 
+                               mValue, mKind == KIND_CONST, pBlock->mCH);
+               else
+                       pMethod->addSlot(mName, mNamespace, mSlotId, pType,     
pBlock->mCH);
+               break;
+       }
+       case KIND_METHOD:
+       {
+               pMethod->addMethod(mName, mNamespace, mMethod);
+               break;
+       }
+       case KIND_GETTER:
+       {
+               pMethod->addGetter(mName, mNamespace, mMethod, pBlock->mCH);
+               break;
+       }
+       case KIND_SETTER:
+       {
+               pMethod->addSetter(mName, mNamespace, mMethod, pBlock->mCH);
+               break;
+       }
+       case KIND_CLASS:
+       {
+               pMethod->addMemberClass(mName, mNamespace, mSlotId,
+                       pBlock->mClasses[mClassInfoIndex]);
+               break;
+       }
+       case KIND_FUNCTION:
+       {
+               pMethod->addSlotFunction(mName, mNamespace, mSlotId, mMethod);
+               break;
+       }
+       default:
+               // Not here -- validated already in read.
+               return false;
+               break;
+       } // end of switch
+       return true;
+}
+
+/// Read an AS3 'trait'
+bool
+abc_Trait::read(stream* in, abc_block *pBlock)
+{
+       uint32_t name = in->read_V32();
+       if (name >= pBlock->mMultinamePool.size())
+       {
+               ERR((_("ABC: Bad name for trait.\n")));
+               return false;
+       }
+       if (!(pBlock->mMultinamePool[name].mFlags & abc_Multiname::FLAG_QNAME))
+       {
+               ERR((_("ABC: Trait name must be fully qualified.\n")));
+               return false;
+       }
+       mName = pBlock->mMultinamePool[name].mName;
+       mNamespace = pBlock->mMultinamePool[name].mNamespace;
 
        uint8_t kind = in->read_u8();
        mKind = static_cast<kinds> (kind & 0x0F);
@@ -46,11 +184,15 @@
        {
                mSlotId = in->read_V32();
                mTypeIndex = in->read_V32();
-               mValueIndex = in->read_V32();
-               if (mValueIndex)
-                       mValueIndexTypeIndex = in->read_u8();
+               uint32_t vindex = in->read_V32();
+               if (vindex)
+               {
+                       if (!pBlock->pool_value(vindex, in->read_u8(), mValue))
+                               return false; // Message done by pool_value
+                       mHasValue = true;
+               }
                else
-                       mValueIndexTypeIndex = 0;
+                       mHasValue = false;
                break;
        }
        case KIND_METHOD:
@@ -60,203 +202,289 @@
                // Ignore the 'disp_id'
                in->skip_V32();
 
-               mMethodInfoIndex = in->read_V32();
+               uint32_t moffset = in->read_V32();
+               if (moffset >= pBlock->mMethods.size())
+               {
+                       ERR((_("Bad method id in trait.\n")));
+                       return false;
+               }
+               mMethod = pBlock->mMethods[moffset];
                break;
        }
        case KIND_CLASS:
        {
                mSlotId = in->read_V32();
                mClassInfoIndex = in->read_V32();
+               if (mClassInfoIndex >= pBlock->mClasses.size())
+               {
+                       ERR((_("Bad Class id in trait.\n")));
+                       return false;
+               }
                break;
        }
        case KIND_FUNCTION:
        {
                mSlotId = in->read_V32();
-               mMethodInfoIndex = in->read_V32();
+               uint32_t moffset = in->read_V32();
+               if (moffset >= pBlock->mMethods.size())
+               {
+                       ERR((_("Bad method id in trait.\n")));
+                       return false;
+               }
+               mMethod = pBlock->mMethods[moffset];
                break;
        }
        default:
        {
-               ERR((_("Action Block: Unknown trait kind (%d).\n"), mKind));
+               ERR((_("ABC: Unknown type of trait.\n")));
                return false;
        }
-       } // end of switch
+       } // end of switch statement
 
-       // Ignore the metadata, but it must be read to know how long it is.
+       // Ignore the metadata, but it must be read to know how to ignore it.
        if ((kind >> 4) & 0x04) // has metadata
        {
-               uint32_t metaCount = in->read_V32();
-               for (unsigned int k = 0; k < metaCount; ++k)
+               uint32_t mcount = in->read_V32();
+               for (unsigned int i = 0; i < mcount; ++i)
                {
                        in->skip_V32();
                }
        }
-
-       return true; // Here, we were successful.
+       return true;
 }
 
 }; // namespace abc_parsing
 
-// Load up all of the data.
-bool
-abc_block::read(stream* in)
+using namespace abc_parsing;
+
+asClass *
+abc_block::locateClass(abc_Multiname &m)
 {
-       using namespace abc_parsing;
-       ClassHierarchy *ch = VM::get().getClassHierarchy();
+       asClass *found = NULL;
+
+       if (m.mNamespace)
+       {
+               found = m.mNamespace->getClass(m.mName);
+               if (found)
+                       return found;
+       }
+       if (m.mNamespaceSet && !m.mNamespaceSet->empty())
+       {
+               std::vector<asNamespace*>::iterator i;
+               for (i = m.mNamespaceSet->begin(); i != m.mNamespaceSet->end(); 
++i)
+               {
+                       found = (*i)->getClass(m.mName);
+                       if (found)
+                               return found;
+               }
+       }
+       // One last chance: Look globally.
+       found = mCH->getGlobalNs()->getClass(m.mName);
+       if (found)
+               return found;
+
+       // Fake it here for a while.
+       if (m.mNamespace)
+       {
+               m.mNamespace->stubPrototype(m.mName);
+               found = m.mNamespace->getClass(m.mName);
+               return found;
+       }
+       else
+       {
+               // Fake in global.
+               mCH->getGlobalNs()->stubPrototype(m.mName);
+               found = mCH->getGlobalNs()->getClass(m.mName);
+               return found;
+       }
+       return NULL;
+}
 
+/// Read the ActionBlock version number.
+bool
+abc_block::read_version()
+{
        // Minor version, major version.
-       uint32_t version = (in->read_u16()) | (in->read_u16() << 16);
-       ERR((_("Abc Version: %d.%d\n"), (version & 0xFFFF0000) >> 16, (version 
& 0x0000FFFF)));
+       mVersion = (mS->read_u16()) | (mS->read_u16() << 16);
+       ERR((_("Abc Version: %d.%d\n"), (mVersion & 0xFFFF0000) >> 16,
+               (mVersion & 0x0000FFFF)));
+       return true;
+}
 
-       // A block of signed integers. Count overshoots by 1,
-       // and the 0 is used to signal a no-op.
-       uint32_t intPoolCount = in->read_V32();
-       mIntegerPool.resize(intPoolCount);
-       if (intPoolCount)
+/// Read the pool of integer constants.
+bool
+abc_block::read_integer_constants()
+{
+       // count overestimates by 1.
+       uint32_t count = mS->read_V32();
+       mIntegerPool.resize(count);
+       if (count)
                mIntegerPool[0] = 0;
-       for (unsigned int i = 1; i < intPoolCount; ++i)
+       for (unsigned int i = 1; i < count; ++i)
        {
-               mIntegerPool[i] = static_cast<int32_t> (in->read_V32());
+               mIntegerPool[i] = static_cast<int32_t> (mS->read_V32());
        }
+       return true;
+}
        
-       // A block of unsigned integers. Count overshoots by 1,
-       // and the 0 is used to signal a no-op.
-       uint32_t uIntPoolCount = in->read_V32();
-       mUIntegerPool.resize(uIntPoolCount);
-       if (uIntPoolCount)
+/// Read the pool of unsigned integer constants.
+bool
+abc_block::read_unsigned_integer_constants()
+{
+       // count overestimates by 1.
+       uint32_t count = mS->read_V32();
+       mUIntegerPool.resize(count);
+       if (count)
                mUIntegerPool[0] = 0;
-       for (unsigned int i = 1; i < uIntPoolCount; ++i)
+       for (unsigned int i = 1; i < count; ++i)
        {
-               mUIntegerPool[i] = in->read_V32();
+               mUIntegerPool[i] = mS->read_V32();
        }
+       return true;
+}
 
-       // A block of 64 bit doubles.  Counter overshoots by 1,
-       // and the 0 is used to signal a no-op.
-       uint32_t doublePoolCount = in->read_V32();
-       mDoublePool.resize(doublePoolCount);
-       if (doublePoolCount)
+/// Read the pool of 64-bit double constants.
+bool
+abc_block::read_double_constants()
+{
+       uint32_t count = mS->read_V32();
+       mDoublePool.resize(count);
+       if (count)
                mDoublePool[0] = 0.0;
-       for (unsigned int i = 1; i < doublePoolCount; ++i)
+       for (unsigned int i = 1; i < count; ++i)
        {
-               mDoublePool[i] = in->read_d64();
+               mDoublePool[i] = mS->read_d64();
        }
+       return true;
+}
 
-       // A block of strings. Counter overshoots by 1, with the 0th
-       // entry used to signal a no-op.
-       uint32_t stringPoolCount = in->read_V32();
-       mStringPool.resize(stringPoolCount);
-       mStringPoolTableIds.resize(stringPoolCount);
-       if (stringPoolCount)
+/// Read the pool of string constants.
+bool
+abc_block::read_string_constants()
+{
+       uint32_t count = mS->read_V32();
+       mStringPool.resize(count);
+       mStringPoolTableIds.resize(count);
+       if (count)
        {
                mStringPool[0] = "";
                mStringPoolTableIds[0] = 0;
        }
-       for (unsigned int i = 1; i < stringPoolCount; ++i)
+       for (unsigned int i = 1; i < count; ++i)
        {
-               uint32_t length = in->read_V32();
-               in->read_string_with_length(length, mStringPool[i]);
+               uint32_t length = mS->read_V32();
+               mS->read_string_with_length(length, mStringPool[i]);
                mStringPoolTableIds[i] = 0;
        }
+       return true;
+}
 
-       // These are namespaces, individually. The counter overshoots by
-       // 1, with the 0th entry used to signal a wildcard.
-       uint32_t namespacePoolCount = in->read_V32();
-       mNamespacePool.resize(namespacePoolCount);
-       if (namespacePoolCount)
+/// Read the pool of namespaces
+/// Any two namespaces with the same uri here are the same namespace,
+/// excepting private namespaces.
+bool
+abc_block::read_namespaces()
+{
+       uint32_t count = mS->read_V32();
+       mNamespacePool.resize(count);
+       if (count)
        {
-               mNamespacePool[0] = ch->getGlobalNs();
+               mNamespacePool[0] = mCH->getGlobalNs();
        }
-       for (unsigned int i = 1; i < namespacePoolCount; ++i)
+       for (unsigned int i = 1; i < count; ++i)
        {
-               uint8_t kind = in->read_u8();
-               if (kind == Namespace::KIND_PACKAGE)
-                       kind = Namespace::KIND_NORMAL;
-               // All namespaces have the same structure, though the usage 
differs.
+               uint8_t kind = mS->read_u8();
+               uint32_t nameIndex = mS->read_V32();
 
-               uint32_t nameIndex = in->read_V32();
-               // Set the name of the namespace.
                if (nameIndex && nameIndex < mStringPool.size())
                {
-                       // If we don't have an index for this yet, do so now.
                        if (mStringPoolTableIds[nameIndex] == 0)
                                mStringPoolTableIds[nameIndex] =
                                        
mStringTable->find(mStringPool[nameIndex]);
-                       // And reset the nameIndex for the uri.
                        nameIndex = mStringPoolTableIds[nameIndex];
                }
                else if (nameIndex >= mStringPool.size())
                {
-                       ERR((_("Action Block: Out of Bound string for 
namespace.\n")));
+                       ERR((_("ABC: Out of bounds string given for 
namespace.\n")));
                        return false;
                }
 
-               // If this is a private namespace, it is special.
-               if (kind == Namespace::KIND_PRIVATE)
+               if (kind == PRIVATE_NS)
                {
-                       // TODO: This is a leak. Plug it.
-                       mNamespacePool[i] = new Namespace(nameIndex, 0, 
static_cast<Namespace::kinds>(kind));
+                       mNamespacePool[i] = mCH->anonNamespace(nameIndex);
+                       mNamespacePool[i]->setPrivate();
                }
                else
                {
-                       // And do the Namespace itself.
-                       Namespace *n = ch->findNamespace(nameIndex);
+                       asNamespace *n = mCH->findNamespace(nameIndex);
                        if (n == NULL)
-                               n = ch->addNamespace(nameIndex, 
-                                       static_cast<Namespace::kinds>(kind));
+                               n = mCH->addNamespace(nameIndex);
                        mNamespacePool[i] = n;
                }
+               if (kind == PROTECTED_NS)
+               {
+                       mNamespacePool[i]->setProtected();
        }
+       }
+       return true;
+}
 
-       // These are sets of namespaces, which use the individual ones above.
-       uint32_t namespaceSetPoolCount = in->read_V32();
-       mNamespaceSetPool.resize(namespaceSetPoolCount);
-       if (namespaceSetPoolCount)
+/// Read the set of sets of namespaces.
+bool
+abc_block::read_namespace_sets()
+{
+       uint32_t count = mS->read_V32();
+       mNamespaceSetPool.resize(count);
+       if (count)
        {
-               // The base namespace set is empty.
                mNamespaceSetPool[0].resize(0);
        }
-       for (unsigned int i = 1; i < namespaceSetPoolCount; ++i)
+       for (unsigned int i = 1; i < count; ++i)
        {
-               // These counts are not inflated the way the others are.
-               uint32_t count = in->read_V32();
-               mNamespaceSetPool[i].resize(count);
-               for (unsigned int j = 0; j < count; ++j)
+               uint32_t icount = mS->read_V32();
+               mNamespaceSetPool[i].resize(icount);
+               for (unsigned int j = 0; j < icount; ++j)
                {
-                       uint32_t selection = in->read_V32();
-                       if (!selection || selection >= namespacePoolCount)
+                       uint32_t selection = mS->read_V32();
+                       if (!selection || selection >= mNamespacePool.size())
                        {
-                               // Reached a bad selection.
-                               ERR((_("Action Block: Out of Bound namespace in 
namespace set.\n")));
+                               ERR((_("ABC: Out of bounds namespace for 
namespace set.\n")));
                                return false;
                        }
                        mNamespaceSetPool[i][j] = mNamespacePool[selection];
                }
        }
+       return true;
+}
 
-       // A list of the multinames. The counter overestimates by 1, and the
-       // 0th is used as a no-op.
-       uint32_t multinamePoolCount = in->read_V32();
-
-       // Any two namespaces with the same uri here are the same namespace,
-       // excepting private nameSpaces.
-       mMultinamePool.resize(multinamePoolCount);
-       for (unsigned int i = 1; i < multinamePoolCount; ++i)
+/// Read the multinames.
+bool
+abc_block::read_multinames()
+{
+       uint32_t count = mS->read_V32();
+       mMultinamePool.resize(count);
+       if (count)
        {
-               uint8_t kind = in->read_u8();
+               mMultinamePool[0].mName = 0;
+               mMultinamePool[0].mNamespace = mCH->getGlobalNs();
+       }
+       for (unsigned int i = 1; i < count; ++i)
+       {
+               uint8_t kind = mS->read_u8();
                uint32_t ns = 0;
                uint32_t name = 0;
                uint32_t nsset = 0;
 
                mMultinamePool[i].mFlags = 0;
 
-               // Read, but don't upper validate until after the switch
+               // Read, but don't upper validate until after the switch.
                switch (kind)
                {
                case abc_Multiname::KIND_Qname:
                case abc_Multiname::KIND_QnameA:
                {
-                       ns = in->read_V32();
-                       name = in->read_V32();
+            ns = mS->read_V32();
+            name = mS->read_V32();
                        mMultinamePool[i].mFlags |= abc_Multiname::FLAG_QNAME;
                        if (kind == abc_Multiname::KIND_QnameA)
                                mMultinamePool[i].mFlags |= 
abc_Multiname::FLAG_ATTR;
@@ -265,7 +493,7 @@
                case abc_Multiname::KIND_RTQname:
                case abc_Multiname::KIND_RTQnameA:
                {
-                       name = in->read_V32();
+            name = mS->read_V32();
                        mMultinamePool[i].mFlags |= abc_Multiname::FLAG_QNAME
                                | abc_Multiname::FLAG_RTNS;
                        if (kind == abc_Multiname::KIND_RTQnameA)
@@ -285,12 +513,12 @@
                case abc_Multiname::KIND_Multiname:
                case abc_Multiname::KIND_MultinameA:
                {
-                       name = in->read_V32();
-                       nsset = in->read_V32();
+            name = mS->read_V32();
+            nsset = mS->read_V32();
                        // 0 is not a valid nsset.
                        if (!nsset)
                        {
-                               ERR((_("Action Block: 0 selection for namespace 
set is invalid.\n")));
+                ERR((_("ABC: 0 selection for namespace set is invalid.\n")));
                                return false;
                        }
                        mMultinamePool[i].mFlags |= abc_Multiname::FLAG_NSSET;
@@ -301,11 +529,11 @@
                case abc_Multiname::KIND_MultinameL:
                case abc_Multiname::KIND_MultinameLA:
                {
-                       nsset = in->read_V32();
+            nsset = mS->read_V32();
                        // 0 is not a valid nsset.
                        if (!nsset)
                        {
-                               ERR((_("Action Block: 0 selection for namespace 
set is invalid.\n")));
+                ERR((_("ABC: 0 selection for namespace set is invalid.\n")));
                                return false;
                        }
                        mMultinamePool[i].mFlags |= abc_Multiname::FLAG_RTNAME
@@ -324,21 +552,21 @@
 
                if (name >= mStringPool.size())
                {
-                       ERR((_("Action Block: Out of Bound string for 
Multiname.\n")));
-                       return false; // Bad name.
+                       ERR((_("ABC: Out of bounds string for Multiname.\n")));
+                       return false;
                }
                if (ns >= mNamespacePool.size())
                {
-                       ERR((_("Action Block: Out of Bound namespace for 
Multiname.\n")));
-                       return false; // Bad namespace.
+                       ERR((_("ABC: Out of bounds namespace for 
Multiname.\n")));
+                       return false;
                }
                if (nsset >= mNamespaceSetPool.size())
                {
-                       ERR((_("Action Block: Out of Bound namespace set for 
Multiname.\n")));
-                       return false; // Bad namespace set.
+                       ERR((_("ABC: Out of bounds namespace set for 
Multiname.\n")));
+                       return false;
                }
 
-               // The name should be in the string table.
+               // Load the string table with the name if not already there.
                if (name && mStringPoolTableIds[name] == 0)
                {
                        mStringPoolTableIds[name] = 
mStringTable->find(mStringPool[name]);
@@ -349,372 +577,585 @@
                        mMultinamePool[i].mNamespace = mNamespacePool[ns];
                if (nsset)
                        mMultinamePool[i].mNamespaceSet = 
&mNamespaceSetPool[nsset];
+       } // End of main loop.
+       return true;
+}
 
-       } // End of multiname loop.
+bool
+abc_block::pool_value(uint32_t index, uint8_t type, as_value &v)
+{
+       if (!index)
+               return true;
+
+       switch (type)
+       {
+       case POOL_STRING: 
+       {
+               if (index >= mStringPool.size())
+               {
+                       ERR((_("Action Block: Bad index in optional 
argument.\n")));
+                       return false;
+               }
+               v.set_string(mStringPool[index]);
+               break;
+       }
+       case POOL_INTEGER: 
+       {
+               if (index >= mIntegerPool.size())
+           {
+                       ERR((_("Action Block: Bad index in optional 
argument.\n")));
+                       return false;
+               }
+               v.set_int(mIntegerPool[index]);
+               break;
+       }
+       case POOL_UINTEGER:
+       {
+               if (index >= mUIntegerPool.size())
+               {
+                       ERR((_("Action Block: Bad index in optional 
argument.\n")));
+                       return false;
+               }
+               v.set_int(mUIntegerPool[index]);
+               break;
+       }
+       case POOL_DOUBLE: 
+       {
+               if (index >= mDoublePool.size())
+               {
+                       ERR((_("Action Block: Bad index in optional 
argument.\n")));
+                       return false;
+               }
+               v.set_double(static_cast<double>(mDoublePool[index]));
+               break;
+       }
+       case POOL_NAMESPACE: // Namespace
+       {
+               if (index >= mNamespacePool.size())
+               {
+                       ERR((_("ABC: Bad index in optional argument, 
namespaces.\n")));
+                       return false;
+               }
+               break;
+       }
+       case POOL_FALSE: // False value
+       {
+               v.set_bool(false);
+               break;
+       }
+       case POOL_TRUE: // True value
+       {
+               v.set_bool(true);
+               break;
+       }
+       case POOL_NULL: // NULL value
+       {
+               v.set_null();
+               break;
+       }
+       default: // All others are bogus.
+       {
+               ERR((_("ABC: Bad default value type (%X), but continuing.\n"), 
type));
+               return true;
+               break;
+       }
+       } // end of switch
+       return true;
+}
 
-       uint32_t methodCount = in->read_V32();
-       mMethods.resize(methodCount);
-       for (unsigned int i = 0; i < methodCount; ++i)
+/// Read the method infos.
+bool
+abc_block::read_method_infos()
+{
+       uint32_t count = mS->read_V32();
+       mMethods.resize(count);
+       for (unsigned int i = 0; i < count; ++i)
        {
-               abc_Method& method = mMethods[i];
+               asMethod *pMethod = mCH->newMethod();
+               mMethods[i] = pMethod;
 
-               uint32_t param_count = in->read_V32();
-               uint32_t return_type = in->read_V32();
+               uint32_t param_count = mS->read_V32();
+               uint32_t return_type = mS->read_V32();
+
+               pMethod->setMinArgumentCount(param_count);
+               pMethod->setMaxArgumentCount(param_count);
 
                if (return_type >= mMultinamePool.size())
                {
-                       ERR((_("Action Block: Out of Bound return type for "
-                               "method info (%d).\n"), return_type));
+                       ERR((_("ABC: Out of bounds return type for method 
info.\n")));
+                       return false;
+               }
+
+               asClass *rtClass = locateClass(mMultinamePool[return_type]);
+               if (!rtClass)
+               {
+                       ERR((_("ABC: Unknown return type.\n")));
                        return false;
                }
 
-               method.mReturnType = &mMultinamePool[return_type];
+               pMethod->setReturnType(rtClass);
 
-               method.mParameters.resize(param_count);
                for (unsigned int j = 0; j < param_count; ++j)
                {
                        // The parameter type.
-                       uint32_t ptype = in->read_V32();
+                       uint32_t ptype = mS->read_V32();
                        if (ptype >= mMultinamePool.size())
                        {
-                               ERR((_("Action Block: Out of Bound parameter 
type "
-                                       "for method info (%d).\n"), ptype));
+                               ERR((_("ABC: Out of bounds parameter type in 
method.\n")));
+                               return false;
+                       }
+                       asClass *param_type = 
locateClass(mMultinamePool[ptype]);
+                       if (!param_type)
+                       {
+                               ERR((_("ABC: Unknown parameter type.\n")));
                                return false;
                        }
-                       method.mParameters[j] = &mMultinamePool[ptype];
+                       pMethod->pushArgument(param_type);
                }
-               // We ignore the name_index
-               in->skip_V32();
 
-               uint8_t flags = in->read_u8();
-               method.mFlags = flags;
+               // A skippable name index.
+               mS->skip_V32();
+
+               uint8_t flags = mS->read_u8();
 
-               // Some parameters have default values.
-               if (flags & abc_Method::FLAG_OPTIONAL)
+               // If there are default parameters, read them now.
+               // Runtime will do validation of whether or not these can 
actually
+               // be assigned to the corresponding parameters.
+               if (flags & METHOD_OPTIONAL_ARGS)
                {
-                       uint32_t count = in->read_V32();
-                       method.mOptionalParameters.resize(count);
-                       for (unsigned int j = 0; j < count; ++j)
+                       uint32_t ocount = mS->read_V32();
+                       
pMethod->setMinArgumentCount(pMethod->maxArgumentCount() - ocount);
+                       for (unsigned int j = 0; j < ocount; ++j)
                        {
-                               // The value index.
-                               method.mOptionalParameters[j].mIndex = 
in->read_V32();
-                               // The value kind.
-                               method.mOptionalParameters[j].mKind = 
in->read_u8();
+                               uint32_t index = mS->read_V32();
+                               uint8_t kindof = mS->read_u8();
+                               as_value v;
+                               if (!pool_value(index, kindof, v))
+                                       return false; // message done by 
pool_value
+                               pMethod->pushOptional(v);
                        }
                }
 
-               // The parameters are given names, which AS3 can't use. We don't
-               // either, since we're not a development environment.
-               if (flags & abc_Method::FLAG_PARAM_NAMES)
+               // If there are names present for the parameters, skip them.
+               if (flags & METHOD_ARG_NAMES)
                {
                        for (unsigned int j = 0; j < param_count; ++j)
                        {
-                               in->skip_V32();
+                               mS->skip_V32();
                        }
                }
        } // End of method loop.
+       return true;
+}
 
-       // Following is MetaData, which we will ignore.
-       uint32_t metaCount = in->read_V32();
-       for (unsigned int i = 0; i < metaCount; ++i)
-       {
-               in->skip_V32(); // A name index.
-               uint32_t metaInternalCount = in->read_V32();
-               for (unsigned int j = 0; j < metaInternalCount; ++j)
+/// Skip the metadata, which is useless to us.
+bool
+abc_block::skip_metadata()
+{
+       uint32_t count = mS->read_V32();
+       for (unsigned int i = 0; i < count; ++i)
                {
-                       // key and values are _not_ in this order (they group 
together), but
-                       // we are just skipping anyway.
-                       in->skip_V32();
-                       in->skip_V32();
+               mS->skip_V32(); // A name index.
+               uint32_t icount = mS->read_V32();
+               for (unsigned int j = 0; j < icount; ++j)
+               {
+                       // key/values may not be stored together, but this 
still works.
+                       mS->skip_V32();
+                       mS->skip_V32();
                }
        }
+       return true;
+}
 
-       // Classes count.
-       uint32_t classCount = in->read_V32();
-       mClasses.resize(classCount);
-
-       // But first, instances, which uses classCount
-       mInstances.resize(classCount);
-       for (unsigned int i = 0; i < classCount; ++i)
+/// Load the instances from the block.
+bool
+abc_block::read_instances()
+{
+       uint32_t count = mS->read_V32();
+       mClasses.resize(count);
+       for (unsigned int i = 0; i < count; ++i)
        {
-               abc_Instance& instance = mInstances[i];
-               uint32_t index = in->read_V32();
+               asClass *pClass;
+
+               uint32_t index = mS->read_V32();
                // 0 is allowed as a name, typically for the last entry.
                if (index >= mMultinamePool.size())
                {
-                       ERR((_("Action Block: Out of Bound instance name 
(%d).\n"), index));
-                       return false; // Name out of bounds.
+                       ERR((_("ABC: Out of bounds instance name.\n")));
+                       return false;
                }
-               instance.mName = &mMultinamePool[index];
-               // This must be a QName, not some other type.
-               if (!(instance.mName->mFlags & abc_Multiname::FLAG_QNAME))
+               // This must be a QName.
+               if (!(mMultinamePool[index].mFlags & abc_Multiname::FLAG_QNAME))
                {
-                       ERR((_("Action Block: Qname required for 
instance.\n")));
-                       return false; // Name not Qname
+                       ERR((_("ABC: QName required for instance.\n")));
+                       return false;
                }
-               
-               uint32_t super_index = in->read_V32();
-               if (!super_index)
-                       instance.mSuperType = NULL;
-               else if (super_index >= mMultinamePool.size())
+               if (mMultinamePool[index].mNamespace == NULL)
                {
-                       ERR((_("Action Block: Out of Bound super type 
(%d).\n"), super_index));
-                       return false; // Bad index.
+                       ERR((_("ABC: No namespace to use for storing 
class.\n")));
+                       return false;
                }
-               else
-                       instance.mSuperType = &mMultinamePool[super_index];
 
-               int found = 0;
-               // If there is a super_index, we ought to be able to find this 
thing.
-               if (super_index)
-               {
-                       if (!instance.mSuperType->mNamespace)
-                       {
-                               if (instance.mSuperType->mNamespaceSet)
+               pClass = locateClass(mMultinamePool[index]);
+               if (!pClass)
                                {
-                                       int found = 0;
-                                       for (std::vector<Namespace*>::iterator 
i = 
-                                               
instance.mSuperType->mNamespaceSet->begin();
-                                               i != 
instance.mSuperType->mNamespaceSet->end();
-                                               ++i)
+                       pClass = mCH->newClass();
+                       if (!mMultinamePool[index].mNamespace->addClass(
+                               mMultinamePool[index].mName, pClass))
                                        {
-                                               if 
((*i)->prototypeExists(super_index))
-                                                       ++found;
+                               ERR((_("Duplicate class registration.\n")));
+                               return false;
                                        }
                                }
+               pClass->setDeclared();
+               mClasses[i] = pClass;
+               uint32_t super_index = mS->read_V32();
+
+               if (super_index && super_index >= mMultinamePool.size())
+               {
+                       ERR((_("ABC: Out of bounds super type.\n")));
+                       return false;
                        }
-                       else if 
(instance.mSuperType->mNamespace->prototypeExists(
-                               instance.mSuperType->mName))
+               if (!super_index)
                        {
-                               ++found;
+                       pClass->setSuper(mTheObject);
                        }
-
-                       if (found == 0)
+               else
                        {
-                               if 
(!ch->getGlobalNs()->prototypeExists(instance.mSuperType->mName))
+                       asClass *pSuper = 
locateClass(mMultinamePool[super_index]);
+                       if (!pSuper)
                                {
-                                       ERR((_("Action Block: Super type not 
found (%s), faking.\n"),
-                                               
mStringTable->value(instance.mSuperType->mName).c_str()));
-                                       // While testing, we will add the super 
to the global object to fake.
-                                       
ch->getGlobalNs()->stubPrototype(instance.mSuperType->mName);
-                                       //return false;
+                               ERR((_("ABC: Super type not found (%s), 
faking.\n"),
+                                       
mStringTable->value(mMultinamePool[super_index].mName).c_str()));
+                               // While testing, we will add a fake type, 
rather than abort.
+                               pSuper = mCH->newClass();
+                               
pSuper->setName(mMultinamePool[super_index].mName);
+                               
mCH->getGlobalNs()->addClass(mMultinamePool[super_index].mName, pSuper);
+                               // return false;
                                }
+
+                       if (pSuper->isFinal())
+                       {
+                               ERR((_("ABC: Can't extend a class which is 
final.\n")));
+                               return false;
+                       }
+
+                       if (pSuper->isInterface())
+                       {
+                               ERR((_("ABC: Can't extend an interface 
type.\n")));
+                               return false;
                        }
-                       else if (found > 1)
+
+                       if (pSuper == pClass)
                        {
-                               ERR((_("Action Block: Ambiguous declaration 
(%s)\n"),
-                                       
mStringTable->value(instance.mSuperType->mName).c_str()));
+                               ERR((_("ABC: Class cannot be its own 
supertype.\n")));
                                return false;
                        }
+                       pClass->setSuper(pSuper);
+                       pSuper->setInherited();
                }
 
-               uint8_t flags = in->read_u8();
-               instance.mFlags = static_cast<abc_Instance::flags> (flags);
+               uint8_t flags = mS->read_u8();
 
-               instance.mProtectedNamespace = NULL;
-               if (flags & abc_Instance::FLAG_PROTECTED_NS) // Protected 
namespace
+               if (flags & INSTANCE_SEALED)
+                       pClass->setSealed();
+               if (flags & INSTANCE_FINAL)
+                       pClass->setFinal();
+               if (flags & INSTANCE_INTERFACE)
+                       pClass->setInterface();
+               if ((flags & 7) == INSTANCE_DYNAMIC)
+                       pClass->setDynamic();
+
+               if (flags & INSTANCE_PROTECTED_NS) // Protected Namespace
                {
-                       uint32_t ns_index = in->read_V32();
+                       uint32_t ns_index = mS->read_V32();
                        if (ns_index >= mNamespacePool.size())
                        {
-                               ERR((_("Action Block: Out of Bound namespace 
for "
-                                       "instance protected namespace 
(%d).\n"), ns_index));
+                               ERR((_("ABC: Out of bounds namespace for 
protected.\n")));
                                return false;
                        }
-                       if (ns_index)
-                               instance.mProtectedNamespace = 
mNamespacePool[ns_index];
+                       // Set the protected namespace's parent, if it exists.
+                       if (pClass->getSuper()->hasProtectedNs())
+                               
mNamespacePool[ns_index]->setParent(pClass->getSuper()->getProtectedNs());
+                       pClass->setProtectedNs(mNamespacePool[ns_index]);
                }
 
-               // Get the interfaces.
-               uint32_t interfaceCount = in->read_V32();
-               instance.mInterfaces.resize(interfaceCount);
-               for (unsigned int j = 0; j < interfaceCount; ++j)
+               // This is the list of interfaces which the instances has 
agreed to
+               // implement. They must be interfaces, and they must exist.
+               uint32_t intcount = mS->read_V32();
+
+               for (unsigned int j = 0; j < intcount; ++j)
                {
-                       uint32_t i_index = in->read_V32();
+                       uint32_t i_index = mS->read_V32();
                        // 0 is allowed as an interface, typically for the last 
one.
                        if (i_index >= mMultinamePool.size())
                        {
-                               ERR((_("Action Block: Out of Bound name for 
interface. "
-                                       "(%d)\n"), i_index));
-                               return false; // Bad read.
-                       }
-                       instance.mInterfaces[j] = &mMultinamePool[i_index];
+                               ERR((_("ABC: Out of bounds name for 
interface.\n")));
+                               return false;
                }
-
-               // Reach into the methods list.
-               uint32_t methodsOffset = in->read_V32();
-               if (methodsOffset >= mMethods.size())
+                       asClass *pInterface = 
locateClass(mMultinamePool[i_index]);
+                       // These may be undefined still, so don't check 
interface just yet.
+                       if (0) //!pInterface || !pInterface->isInterface())
                {
-                       ERR((_("Action Block: Out of Bound method for 
interface. (%d)\n"),
-                               methodsOffset));
-                       return false; // Bad method.
+                               ERR((_("ABC: Can't implement a non-interface 
type.\n")));
+                               return false;
+                       }
+                       pClass->pushInterface(pInterface);
                }
-               instance.mMethod = &mMethods[methodsOffset];
 
-               // Now parse the traits.
-               // How many of them.
-               uint32_t traitsCount = in->read_V32();
-               instance.mTraits.resize(traitsCount);
-               for (unsigned int j = 0; j < traitsCount; ++j)
+               // The next thing should be the constructor.
+               // TODO: What does this mean exactly? How does it differ from 
the one in
+               // the class info block?
+               uint32_t moffset = mS->read_V32();
+               if (moffset >= mMethods.size())
                {
-                       if (!instance.mTraits[j].read(in))
+                       ERR((_("ABC: Out of bounds method for 
initializer.\n")));
                                return false;
                }
-
-               if (instance.mName->mNamespace == NULL)
+               if (mMethods[moffset]->getOwner())
                {
-                       ERR((_("Action Block: No namespace to use for storing 
class.\n")));
+                       ERR((_("ABC: Initializer method already bound.\n")));
                        return false;
                }
-               if 
(!instance.mName->mNamespace->stubPrototype(instance.mName->mName))
-               {
-                       ERR((_("Duplicate class registration for type %s.\n"),
-                               
mStringTable->value(instance.mName->mName).c_str()));
+               pClass->setConstructor(mMethods[moffset]);
+               mMethods[moffset]->setOwner(pClass);
+
+               // Next come the 'traits' of the instance. (The members.)
+               uint32_t tcount = mS->read_V32();
+               for (unsigned int j = 0; j < tcount; ++j)
+               {
+                       abc_Trait &aTrait = newTrait();
+                       aTrait.set_target(pClass, false);
+                       if (!aTrait.read(mS, this))
                        return false;
                }
-       } // end of instances list
+       } // End of instances loop.
+       return true;
+}
 
-       // Now the classes are read. TODO: Discover what these do.
-       for (unsigned int i = 0; i < classCount; ++i)
+/// Read the class data
+bool
+abc_block::read_classes()
+{
+       // Count was found in read_instances().
+       uint32_t count = mClasses.size();
+
+       for (unsigned int i = 0; i < count; ++i)
        {
-               abc_Class& cClass = mClasses[i];
-               uint32_t method_offset = in->read_V32();
-               if (method_offset >= mMethods.size())
+               asClass *pClass = mClasses[i];
+               uint32_t moffset = mS->read_V32();
+               if (moffset >= mMethods.size())
+               {
+                       ERR((_("ABC: Out of bound static constructor for 
class.\n")));
+                       return false;
+               }
+               if (mMethods[moffset]->getOwner())
                {
-                       ERR((_("Action Block: Out of Bound method for class 
(%d).\n"),
-                               method_offset));
+                       ERR((_("ABC: Static constructor method already 
bound.\n")));
                        return false;
                }
-               cClass.mMethod = &mMethods[method_offset];
+               pClass->setStaticConstructor(mMethods[moffset]);
+               mMethods[moffset]->setOwner(pClass);
 
-               uint32_t traitsCount = in->read_V32();
-               cClass.mTraits.resize(traitsCount);
-               for (unsigned int j = 0; j < traitsCount; ++j)
+               uint32_t tcount = mS->read_V32();
+               for (unsigned int j = 0; j < tcount; ++j)
                {
-                       if (!cClass.mTraits[j].read(in))
+                       abc_Trait &aTrait = newTrait();
+                       aTrait.set_target(pClass, true);
+                       if (!(aTrait.read(mS, this)))
                                return false;
                }
-       } // end of classes list
+       } // end of classes loop
+       return true;
+}
+
+/// Read the scripts (global functions)
+/// The final script is the entry point for the block.
+bool
+abc_block::read_scripts()
+{
+       uint32_t count = mS->read_V32();
 
-       // The scripts. TODO: Discover what these do.
-       uint32_t scriptCount = in->read_V32();
-       mScripts.resize(scriptCount);
-       for (unsigned int i = 0; i < scriptCount; ++i)
+       mScripts.resize(count);
+       for (unsigned int i = 0; i < count; ++i)
        {
-               abc_Script& script = mScripts[i];
-               uint32_t method_offset = in->read_V32();
-               if (method_offset >= mMethods.size())
+               asClass *pScript = mCH->newClass();
+               mScripts[i] = pScript;
+
+               uint32_t moffset = mS->read_V32();
+               if (moffset >= mMethods.size())
                {
-                       ERR((_("Action Block: Out of Bound method for script 
(%d).\n"),
-                               method_offset));
+                       ERR((_("ABC: Out of bounds method for script.\n")));
                        return false;
                }
-               script.mMethod = &mMethods[method_offset];
-
-               uint32_t traitsCount = in->read_V32();
-               script.mTraits.resize(traitsCount);
-               for (unsigned int j = 0; j < traitsCount; ++j)
+               if (mMethods[moffset]->getOwner())
                {
-                       if (!script.mTraits[j].read(in))
+                       ERR((_("ABC: Global script initializer is already 
bound.\n")));
                                return false;
                }
+               mMethods[moffset]->setOwner(pScript);
+               pScript->setConstructor(mMethods[moffset]);
+               pScript->setSuper(mTheObject);
+
+               uint32_t tcount = mS->read_V32();
+               for (unsigned int j = 0; j < tcount; ++j)
+               {
+                       abc_Trait &aTrait = newTrait();
+                       aTrait.set_target(pScript, false);
+                       if (!(aTrait.read(mS, this)))
+                               return false;
        }
+       } // end of scripts loop
+       return true;
+}
 
-       // The method bodies. TODO: Use these.
-       uint32_t methodBodyCount = in->read_V32();
-       mBodies.resize(methodBodyCount);
-       for (unsigned int i = 0; i < methodBodyCount; ++i)
+/// Read the method bodies and attach them to the methods.
+bool
+abc_block::read_method_bodies()
+{
+       uint32_t count = mS->read_V32();
+
+       for (unsigned int i = 0; i < count; ++i)
        {
-               abc_MethodBody& method = mBodies[i];
+               asMethodBody *pBody = mCH->newMethodBody();
 
-               uint32_t method_info = in->read_V32();
-               if (method_info >= mMethods.size())
+               uint32_t moffset = mS->read_V32();
+               if (moffset >= mMethods.size())
+               {
+                       ERR((_("ABC: Out of bounds for method body.\n")));
+                       return false;
+               }
+               if (mMethods[moffset]->getBody())
                {
-                       ERR((_("Action Block: Out of Bound method for method 
body. "
-                               "(%d)\n"), method_info));
-                       return false; // Too big.
+                       ERR((_("ABC: Only one body per method.\n")));
+                       return false;
                }
-               method.mMethod = &mMethods[method_info];
+               mMethods[moffset]->setBody(pBody);
 
-               // We don't care about the maximum stack size. Discard it.
-               in->skip_V32();
-               // We don't care about the maximum register size. Discard it.
-               in->skip_V32();
-               // What to do with the scope depth?
-               in->skip_V32();
-               // What to do with the max scope depth?
-               in->skip_V32();
-               // How long is the code?
-               uint32_t code_length = in->read_V32();
-               // And the code:
-               method.mCode.resize(code_length);
+               // Maximum stack size.
+               mS->skip_V32();
+               // Maximum register size.
+               mS->skip_V32();
+               // Scope depth.
+               mS->skip_V32();
+               // Max scope depth.
+               mS->skip_V32();
+               // Code length
+               uint32_t clength = mS->read_V32();
+               // The code.
+               pBody->setSize(clength);
                unsigned int got_length;
-               if ((got_length = in->read(&method.mCode.front(), code_length)) 
!= code_length)
+               if ((got_length = mS->read(pBody->getRaw(), clength)) != 
clength)
                {
-                       ERR((_("Action Block: Not enough body. Wanted %d but 
got %d.\n"),
-                               code_length, got_length));
-                       return false; // Not enough bytes.
+                       ERR((_("ABC: Not enough method body. Wanted %d but got 
%d.\n"),
+                               pBody->getSize(), got_length));
+                       return false;
                }
 
-               // TODO: Grab code_length bytes for the code.
-               uint32_t exceptions_count = in->read_V32();
-               method.mExceptions.resize(exceptions_count);
-               for (unsigned int j = 0; j < exceptions_count; ++j)
+               uint32_t ecount = mS->read_V32();
+               for (unsigned int j = 0; j < ecount; ++j)
                {
-                       abc_Exception& exceptor = method.mExceptions[j];
+                       asException *pExcept = mCH->newException();
 
                        // Where the try block begins and ends.
-                       exceptor.mStart = in->read_V32();
-                       exceptor.mEnd = in->read_V32();
+                       pExcept->setStart(mS->read_V32());
+                       pExcept->setEnd(mS->read_V32());
                        
-                       // Where to go if this exception is activated.
-                       exceptor.mCatch = in->read_V32();
+                       // Where to go when the exception is activated.
+                       pExcept->setCatch(mS->read_V32());
                        
                        // What types should be caught.
-                       uint32_t catch_type = in->read_V32();
+                       uint32_t catch_type = mS->read_V32();
                        if (catch_type >= mMultinamePool.size())
                        {
-                               ERR((_("Action Block: Out of Bound type for 
exception "
-                                       "(%d).\n"), catch_type));
-                               return false; // Bad type.
+                               ERR((_("ABC: Out of bound type for 
exception.\n")));
+                               return false;
+                       }
+                       if (!catch_type)
+                       {
+                               pExcept->catchAny();
+                       }
+                       else
+                       {
+                               asClass *pType = 
locateClass(mMultinamePool[catch_type]);
+                               if (!pType)
+                               {
+                                       ERR((_("ABC: Unknown type of object to 
catch. (%s)\n"),
+                                               
mStringTable->value(mMultinamePool[catch_type].mName).c_str()));
+                                       // return false;
+                                       // Fake it, for now:
+                                       pExcept->catchAny();
+                               }
+                               else
+                               {
+                                       pExcept->setCatchType(pType);
+                               }
                        }
-                       exceptor.mType = catch_type ? 
&mMultinamePool[catch_type] : NULL;
 
-                       // If caught, what is the variable name.
-                       if (version != (46 << 16) | 15) // In version 46.15, no 
names.
+                       // A variable name for the catch type.
+                       // In version 46.15, no names.
+                       if (mVersion != (46 << 16) | 15)
                        {
-                               uint32_t cvn = in->read_V32();
+                               uint32_t cvn = mS->read_V32();
                                if (cvn >= mMultinamePool.size())
                                {
-                                       ERR((_("Action Block: Out of Bound name 
for caught "
-                                               "exception. (%d)\n"), cvn));
-                                       return false; // Bad name
+                                       ERR((_("ABC: Out of bound name for 
caught exception.\n")));
+                                       return false;
                                }
-                               exceptor.mName = cvn ? &mMultinamePool[cvn] : 
NULL;
+                               pExcept->setName(mMultinamePool[cvn].mName);
+                               
pExcept->setNamespace(mMultinamePool[cvn].mNamespace);
                        }
-                       else
-                               exceptor.mName = NULL;
-               } // End of exceptions
+               } // end of exceptions
 
-               uint32_t traitsCount = in->read_V32();
-               method.mTraits.resize(traitsCount);
-               for (unsigned int j = 0; j < traitsCount; ++j)
+               uint32_t tcount = mS->read_V32();
+               for (unsigned int j = 0; j < tcount; ++j)
                {
-                       if (!method.mTraits[j].read(in))
+                       abc_Trait &aTrait = newTrait();
+                       aTrait.set_target(mMethods[moffset]);
+                       if (!aTrait.read(mS, this)) // TODO: 'method body 
activation traits'
                                return false;
                }
-       } // End of method bodies
+       } // end of bodies loop
+       return true;
+}
 
-       // Everything has been read. It needs to be verified, with symbol tables
-       // built to make it all run.
+// Load up all of the data.
+bool
+abc_block::read(stream* in)
+{
+       mS = in;
+       if (!read_version()) return false;
+       if (!read_integer_constants()) return false;
+       if (!read_unsigned_integer_constants()) return false;
+       if (!read_double_constants()) return false;
+       if (!read_string_constants()) return false;
+       if (!read_namespaces()) return false;
+       if (!read_namespace_sets()) return false;
+       if (!read_multinames()) return false;
+       if (!read_method_infos()) return false;
+       if (!skip_metadata()) return false;
+       if (!read_instances()) return false;
+       if (!read_classes()) return false;
+       if (!read_scripts()) return false;
+       if (!read_method_bodies()) return false;
        
-       // If flow reaches here, everything went fine.
+       std::vector<abc_Trait*>::iterator i = mTraits.begin();
+       for ( ; i != mTraits.end(); ++i)
+       {
+               if (!(*i)->finalize(this))
+                       return false;
+       }
+       mTraits.clear();
+       mCH->dump();
        return true;
 }
 
 abc_block::abc_block() : mStringTable(&VM::get().getStringTable())
 {
-       /**/
+       mCH = VM::get().getClassHierarchy();
+       // TODO: Make this the real 'Object' prototype.
+       mCH->getGlobalNs()->stubPrototype(NSV::CLASS_OBJECT);
+       mTheObject = mCH->getGlobalNs()->getClass(NSV::CLASS_OBJECT);
 }
 
 }; /* namespace gnash */

Index: server/parser/abc_block.h
===================================================================
RCS file: /sources/gnash/gnash/server/parser/abc_block.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/parser/abc_block.h   24 Sep 2007 15:39:31 -0000      1.4
+++ server/parser/abc_block.h   29 Sep 2007 08:24:21 -0000      1.5
@@ -28,13 +28,14 @@
 #include "gnash.h"
 #include "stream.h"
 #include "string_table.h"
-#include "Namespace.h"
+#include "asClass.h"
 
 namespace gnash {
 
-typedef std::vector<Namespace *> abcNamespaceSet;
+typedef std::vector<asNamespace *> abcNamespaceSet;
 
 class abc_block;
+class ClassHierarchy;
 
 namespace abc_parsing {
 
@@ -67,57 +68,11 @@
 
        uint8_t mFlags;
        string_table::key mName;
-       Namespace* mNamespace;
-       std::vector<Namespace*> *mNamespaceSet;
-};
-
-class abc_Method
-{
-public:
-       typedef enum
-       {
-               FLAG_ARGS = 0x01,
-               FLAG_ACTIVATION = 0x02,
-               FLAG_MORE = 0x04,
-               FLAG_OPTIONAL = 0x08,
-               FLAG_IGNORE = 0x10,
-               FLAG_NATIVE = 0x20,
-               FLAG_DEFAULT_NS = 0x40,
-               FLAG_PARAM_NAMES = 0x80
-       } flags;
-
-       class optional_parameter
-       {
-       public:
-               uint32_t mIndex;
-               uint8_t mKind;
-       };
+       asNamespace* mNamespace;
+       std::vector<asNamespace*> *mNamespaceSet;
 
-       abc_Multiname *mReturnType;
-       std::vector<abc_Multiname*> mParameters; // The types, not the names.
-       uint8_t mFlags;
-       std::vector<optional_parameter> mOptionalParameters;
-};
-
-class abc_Instance
-{
-public:
-       typedef enum
-       {
-               FLAG_SEALED = 0x01,
-               FLAG_FINAL = 0x02,
-               FLAG_INTERFACE = 0x04,
-               FLAG_PROTECTED_NS = 0x08,
-               FLAG_DYNAMIC = 0x00 // No other flags set
-       } flags;
-
-       abc_Multiname *mName;
-       abc_Multiname *mSuperType;
-       flags mFlags;
-       Namespace *mProtectedNamespace;
-       std::vector<abc_Multiname*> mInterfaces;
-       abc_Method *mMethod;
-       std::vector<abc_Trait> mTraits;
+       abc_Multiname() : mFlags(0), mName(0), mNamespace(NULL), 
mNamespaceSet(NULL)
+       {/**/}
 };
 
 class abc_Trait
@@ -134,79 +89,128 @@
                KIND_FUNCTION = 5
        } kinds;
 
+       bool mHasValue;
        kinds mKind;
-       uint32_t mNameIndex;
-       uint32_t mNamespaceIndex;
-       uint32_t mNamespaceSetIndex;
        uint32_t mSlotId;
        uint32_t mTypeIndex;
-       uint32_t mValueIndex;
-       uint8_t mValueIndexTypeIndex;
        uint32_t mClassInfoIndex;
-       uint32_t mMethodInfoIndex;
-
-       bool read(stream* in);
-};
-
-class abc_Class
-{
-public:
-       abc_Method *mMethod;
-       std::vector<abc_Trait> mTraits;
-};
-
-class abc_Script
-{
-public:
-       abc_Method *mMethod;
-       std::vector<abc_Trait> mTraits;
-};
-
-class abc_Exception
-{
-public:
-       uint32_t mStart;
-       uint32_t mEnd;
-       uint32_t mCatch;
-       abc_Multiname* mType;
-       abc_Multiname* mName;
-};
-
-class abc_MethodBody
-{
-public:
-       abc_Method *mMethod;
-       std::vector<abc_Exception> mExceptions;
-       std::vector<abc_Trait> mTraits;
-       std::vector<char> mCode;
+       as_value mValue;
+       string_table::key mName;
+       asNamespace *mNamespace;
+       asMethod *mMethod;
+       bool mValueSet;
+
+       asClass *mCTarget;
+       asMethod *mMTarget;
+       bool mStatic;
+
+       abc_Trait() : mHasValue(false), mKind(KIND_SLOT), mSlotId(0),
+               mTypeIndex(0), mClassInfoIndex(0), mValue(), mName(0),
+               mNamespace(NULL), mMethod(NULL), mValueSet(false)
+       {/**/}
+
+       bool read(stream* in, abc_block *pBlock);
+       bool finalize(abc_block *pBlock, asClass *pClass, bool do_static);
+       bool finalize_mbody(abc_block *pBlock, asMethod *pMethod);
+
+       void set_target(asClass *pClass, bool do_static)
+       { mCTarget = pClass; mStatic = do_static; }
+       void set_target(asMethod *pMethod)
+       { mCTarget = NULL; mMTarget = pMethod; }
+
+       bool finalize(abc_block *pBlock)
+       {
+               if (mCTarget)
+                       return finalize(pBlock, mCTarget, mStatic);
+               return finalize_mbody(pBlock, mMTarget);
+       }
 };
 
 }; // namespace abc_parsing
 
-typedef std::vector<Namespace*> NamespaceSet;
+typedef std::vector<asNamespace*> NamespaceSet;
                        
 class abc_block
 {
 private:
+       friend class abc_parsing::abc_Trait;
+       typedef enum
+       {
+               PRIVATE_NS = 0x05,
+               PROTECTED_NS = 0x18,
+               METHOD_ARGS = 0x01,
+               METHOD_ACTIVATION = 0x02,
+               METHOD_MORE = 0x04,
+               METHOD_OPTIONAL_ARGS = 0x08,
+               METHOD_IGNORE = 0x10,
+               METHOD_NATIVE = 0x20,
+               METHOD_DEFAULT_NS = 0x40,
+               METHOD_ARG_NAMES = 0x80,
+               INSTANCE_SEALED = 0x01,
+               INSTANCE_FINAL = 0x02,
+               INSTANCE_INTERFACE = 0x04,
+               INSTANCE_DYNAMIC = 0x00,
+               INSTANCE_PROTECTED_NS = 0x08,
+               POOL_STRING = 0x01,
+               POOL_INTEGER = 0x03,
+               POOL_UINTEGER = 0x04,
+               POOL_DOUBLE = 0x06,
+               POOL_NAMESPACE = 0x08,
+               POOL_FALSE = 0x0A,
+               POOL_TRUE = 0x0B,
+               POOL_NULL = 0x0C
+       } constants;
+
        std::vector<int32_t> mIntegerPool;
        std::vector<uint32_t> mUIntegerPool;
        std::vector<long double> mDoublePool;
        std::vector<std::string> mStringPool;
        std::vector<string_table::key> mStringPoolTableIds;
-       std::vector<Namespace*> mNamespacePool;
+       std::vector<asNamespace*> mNamespacePool;
        std::vector<NamespaceSet> mNamespaceSetPool;
-       std::vector<abc_parsing::abc_Method> mMethods;
+       std::vector<asMethod*> mMethods;
        std::vector<abc_parsing::abc_Multiname> mMultinamePool;
-       std::vector<abc_parsing::abc_Instance> mInstances;
-       std::vector<abc_parsing::abc_Class> mClasses; 
-       std::vector<abc_parsing::abc_Script> mScripts;
-       std::vector<abc_parsing::abc_MethodBody> mBodies;
+       std::vector<asClass*> mClasses; 
+       std::vector<asClass*> mScripts;
+       std::vector<abc_parsing::abc_Trait*> mTraits;
 
        string_table* mStringTable;
+       stream *mS; // Not stored beyond one read.
+
+       asClass *mTheObject;
+       ClassHierarchy *mCH;
+
+       uint32_t mVersion;
+
+       asClass *locateClass(abc_parsing::abc_Multiname &m);
+
+       abc_parsing::abc_Trait &newTrait()
+       {
+               abc_parsing::abc_Trait *p = new abc_parsing::abc_Trait;
+               mTraits.push_back(p);
+               return *p;
+       }
+
+public:
+       bool read_version();
+       bool read_integer_constants();
+       bool read_unsigned_integer_constants();
+       bool read_double_constants();
+       bool read_string_constants();
+       bool read_namespaces();
+       bool read_namespace_sets();
+       bool read_multinames();
+       bool read_method_infos();
+       bool skip_metadata();
+       bool read_instances();
+       bool read_classes();
+       bool read_scripts();
+       bool read_method_bodies();
 
-public:
        bool read(stream* in);
 
+       bool pool_value(uint32_t index, uint8_t type, as_value &v);
+
        abc_block();
 };
 

Index: server/vm/VM.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/VM.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/vm/VM.cpp    24 Sep 2007 15:39:31 -0000      1.21
+++ server/vm/VM.cpp    29 Sep 2007 08:24:22 -0000      1.22
@@ -16,7 +16,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: VM.cpp,v 1.21 2007/09/24 15:39:31 cmusick Exp $ */
+/* $Id: VM.cpp,v 1.22 2007/09/29 08:24:22 cmusick Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -155,6 +155,8 @@
        {
                (*i)->setReachable();
        }
+
+       mClassHierarchy->markReachableResources();
 #endif
 
 }

Index: testsuite/samples/.cvsignore
===================================================================
RCS file: /sources/gnash/gnash/testsuite/samples/.cvsignore,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- testsuite/samples/.cvsignore        4 May 2007 09:49:00 -0000       1.6
+++ testsuite/samples/.cvsignore        29 Sep 2007 08:24:22 -0000      1.7
@@ -13,3 +13,6 @@
 GotoAndPlayTestRunner
 gotoFrameOnKeyEvent-TestRunner
 gmon.out
+subshapes-TestRunner
+BitsReaderTest
+StreamTest

Index: extensions/dbus/.cvsignore
===================================================================
RCS file: extensions/dbus/.cvsignore
diff -N extensions/dbus/.cvsignore
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ extensions/dbus/.cvsignore  29 Sep 2007 08:24:20 -0000      1.1
@@ -0,0 +1,3 @@
+.deps
+Makefile
+Makefile.in

Index: extensions/lirc/.cvsignore
===================================================================
RCS file: extensions/lirc/.cvsignore
diff -N extensions/lirc/.cvsignore
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ extensions/lirc/.cvsignore  29 Sep 2007 08:24:20 -0000      1.1
@@ -0,0 +1,3 @@
+.deps
+Makefile
+Makefile.in

Index: libmedia/.cvsignore
===================================================================
RCS file: libmedia/.cvsignore
diff -N libmedia/.cvsignore
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ libmedia/.cvsignore 29 Sep 2007 08:24:21 -0000      1.1
@@ -0,0 +1,5 @@
+.libs
+Makefile
+Makefile.in
+*.la
+*.lo

Index: server/asClass.cpp
===================================================================
RCS file: server/asClass.cpp
diff -N server/asClass.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asClass.cpp  29 Sep 2007 08:24:21 -0000      1.1
@@ -0,0 +1,339 @@
+// 
+//   Copyright (C) 2007 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#include "asClass.h"
+#include "ClassHierarchy.h"
+#include "VM.h"
+
+namespace gnash {
+
+#define STV(x) VM::get().getStringTable().value(x).c_str()
+
+void
+asNamespace::stubPrototype(string_table::key name)
+{
+       asClass *pClass = VM::get().getClassHierarchy()->newClass();
+       pClass->setName(name);
+       addClass(name, pClass);
+}
+
+bool
+asMethod::addValue(string_table::key name, asNamespace *ns, uint32_t slotId,
+       asClass *type, as_value& val, bool isconst, ClassHierarchy *CH)
+{
+       asBoundValue *bv = CH->newBoundValue();
+       bv->setType(type);
+       bv->setValue(val);
+       return addBinding(name, asBinding(ns, bv, slotId, isconst, false));
+}
+
+bool
+asMethod::addSlot(string_table::key name, asNamespace *ns, uint32_t slotId,
+       asClass *type, ClassHierarchy *CH)
+{
+       asBoundValue *bv = CH->newBoundValue();
+       bv->setType(type);
+       return addBinding(name, asBinding(ns, bv, slotId, false));
+}
+
+bool
+asMethod::addMethod(string_table::key name, asNamespace *ns, asMethod *method)
+{
+       return addBinding(name, asBinding(ns, method, false));
+}
+
+bool
+asMethod::addGetter(string_table::key name, asNamespace *ns, asMethod *method,
+       ClassHierarchy *CH)
+{
+       asBinding *bv = getBinding(name);
+       if (bv)
+       {
+               asBoundAccessor *a = bv->getAccessor();
+               if (!a)
+               {
+                       // Okay if this is already bound to a value.
+                       asBoundValue *v = bv->getValue();
+                       if (!v)
+                       {
+                               // Let caller do the logging.
+                               return false;
+                       }
+                       a = CH->newBoundAccessor();
+                       a->setValue(v);
+                       bv->reset(a, bv->isStatic());
+               }
+               return a->setGetter(method);
+       }
+       asBoundAccessor *a = CH->newBoundAccessor();
+       a->setGetter(method);
+       return addBinding(name, asBinding(ns, a, false));
+}
+
+bool
+asMethod::addSetter(string_table::key name, asNamespace *ns, asMethod *method,
+       ClassHierarchy *CH)
+{
+       asBinding *bv = getBinding(name);
+       if (bv)
+       {
+               asBoundAccessor *a = bv->getAccessor();
+               if (!a)
+               {
+                       asBoundValue *v = bv->getValue();
+                       if (!v)
+                       {
+                               // Let caller do the logging.
+                               return false;
+                       }
+                       a = CH->newBoundAccessor();
+                       a->setValue(v);
+                       bv->reset(a, bv->isStatic());
+               }
+               return a->setSetter(method);
+       }
+       asBoundAccessor *a = CH->newBoundAccessor();
+       addBinding(name, asBinding(ns, a, false));
+       return a->setSetter(method);
+}
+
+bool
+asMethod::addMemberClass(string_table::key name, asNamespace *ns,
+       uint32_t slotId, asClass *type)
+{
+       return addBinding(name, asBinding(ns, type, slotId, false));
+}
+
+// TODO: Figure out how this differs from addMethod
+bool
+asMethod::addSlotFunction(string_table::key name, asNamespace *ns,
+       uint32_t slotId, asMethod *method)
+{
+       return addBinding(name, asBinding(ns, method, slotId, false));
+}
+
+bool
+asClass::addValue(string_table::key name, asNamespace *ns, uint32_t slotId,
+       asClass *type, as_value& val, bool isconst, bool isstatic,
+       ClassHierarchy *CH)
+{
+       asBoundValue *bv = CH->newBoundValue();
+       bv->setType(type);
+       bv->setValue(val);
+       if (!isstatic)
+               return addBinding(name, asBinding(ns, bv, slotId, isconst, 
isstatic));
+       return addStaticBinding(name, asBinding(ns, bv, slotId, isconst, 
isstatic));
+}
+
+bool
+asClass::addSlot(string_table::key name, asNamespace *ns, uint32_t slotId,
+       asClass *type, bool isstatic, ClassHierarchy *CH)
+{
+       asBoundValue *bv = CH->newBoundValue();
+       bv->setType(type);
+       if (!isstatic)
+               return addBinding(name, asBinding(ns, bv, slotId, isstatic));
+       return addStaticBinding(name, asBinding(ns, bv, slotId, isstatic));
+}
+
+bool
+asClass::addMethod(string_table::key name, asNamespace *ns, asMethod *method,
+       bool isstatic)
+{
+       if (!isstatic)
+               return addBinding(name, asBinding(ns, method, isstatic));
+       else
+               return addStaticBinding(name, asBinding(ns, method, isstatic));
+}
+
+bool
+asClass::addGetter(string_table::key name, asNamespace *ns, asMethod *method,
+       bool isstatic, ClassHierarchy *CH)
+{
+       asBinding *bv;
+       if (!isstatic)
+               bv = getBinding(name);
+       else
+               bv = getStaticBinding(name);
+       if (bv)
+       {
+               asBoundAccessor *a = bv->getAccessor();
+               if (!a)
+               {
+                       // Okay if this is already bound to a value.
+                       asBoundValue *v = bv->getValue();
+                       if (!v)
+                       {
+                               // Let caller do the logging.
+                               return false;
+                       }
+                       a = CH->newBoundAccessor();
+                       a->setValue(v);
+                       bv->reset(a, bv->isStatic());
+               }
+               return a->setGetter(method);
+       }
+       asBoundAccessor *a = CH->newBoundAccessor();
+       a->setGetter(method);
+       if (!isstatic)
+               return addBinding(name, asBinding(ns, a, isstatic));
+       return addStaticBinding(name, asBinding(ns, a, isstatic));
+}
+
+bool
+asClass::addSetter(string_table::key name, asNamespace *ns, asMethod *method,
+       bool isstatic, ClassHierarchy *CH)
+{
+       asBinding *bv;
+       if (!isstatic)
+               bv = getBinding(name);
+       else
+               bv = getStaticBinding(name);
+
+       if (bv)
+       {
+               asBoundAccessor *a = bv->getAccessor();
+               if (!a)
+               {
+                       asBoundValue *v = bv->getValue();
+                       if (!v)
+                       {
+                               // Let caller do the logging.
+                               return false;
+                       }
+                       a = CH->newBoundAccessor();
+                       a->setValue(v);
+                       bv->reset(a, bv->isStatic());
+               }
+               return a->setSetter(method);
+       }
+       asBoundAccessor *a = CH->newBoundAccessor();
+       a->setSetter(method);
+       if (!isstatic)
+               return addBinding(name, asBinding(ns, a, isstatic));
+       else
+               return addStaticBinding(name, asBinding(ns, a, isstatic));
+}
+
+bool
+asClass::addMemberClass(string_table::key name, asNamespace *ns,
+       uint32_t slotId, asClass *type, bool isstatic)
+{
+       if (!isstatic)
+               return addBinding(name, asBinding(ns, type, slotId, isstatic));
+       return addStaticBinding(name, asBinding(ns, type, slotId, isstatic));
+}
+
+// TODO: Figure out how this differs from addMethod
+bool
+asClass::addSlotFunction(string_table::key name, asNamespace *ns,
+       uint32_t slotId, asMethod *method, bool isstatic)
+{
+       if (!isstatic)
+               return addBinding(name, asBinding(ns, method, slotId, 
isstatic));
+       return addStaticBinding(name, asBinding(ns, method, slotId, isstatic));
+}
+
+void
+asNamespace::dump()
+{
+       container::iterator i;
+       for (i = mClasses.begin(); i != mClasses.end(); ++i)
+       {
+               if (!((*i->second).isDeclared()))
+               {
+                       if (i->second->isSystem())
+                               fprintf(stderr, "(Known to internals) ");
+                       fprintf(stderr, "%s.%s\n", STV(getURI()),
+                               STV(i->second->getName()));
+//             else
+//                     (*i->second).dump();
+               }
+       }
+}
+
+void
+asClass::dump()
+{
+       binding_container::iterator i;
+       fprintf(stderr, "Class: %s\n", STV(getName()));
+       for (i = mBindings.begin(); i != mBindings.end(); ++i)
+       {
+               fprintf(stderr, "    ");
+               i->second.dump(i->first);
+       }
+}
+
+void
+asBinding::dump(string_table::key name)
+{
+       if (mNamespace->isProtected())
+               fprintf(stderr, "+");
+       if (mNamespace->isPrivate())
+               fprintf(stderr, "#");
+       if (mConst)
+               fprintf(stderr, "@");
+       fprintf(stderr, "%s: ", STV(name));
+       switch (mType)
+       {
+       case T_CLASS:
+       {
+               fprintf(stderr, "Class %s", STV(mClass->getName()));
+               break;
+       }
+       case T_METHOD:
+       {
+//             if (mConst)
+                       fprintf(stderr, "Member Function: %s", 
STV(mMethod->getReturnType()->getName()));
+//             else
+//                     fprintf(stderr, "Function Slot");
+               break;
+       }
+       case T_VALUE:
+       {
+               if (mValue->getType())
+                       fprintf(stderr, "Value of type %s", 
STV(mValue->getType()->getName()));
+               else
+                       fprintf(stderr, "Value of unknown type.");
+               break;
+       }
+       case T_ACCESS:
+       {
+               fprintf(stderr, "GetSet: ");
+               if (mAccess->getGetter())
+               {
+                       fprintf(stderr, "g:%s ", 
STV(mAccess->getGetter()->getReturnType()->getName()));
+               }
+               if (mAccess->getSetter())
+               {
+                       fprintf(stderr, "s ");
+               }
+               if (mAccess->getValue())
+               {
+                       fprintf(stderr, "dv: ");
+                       if (mAccess->getValue()->getType())
+                               fprintf(stderr, "%s ", 
STV(mAccess->getValue()->getType()->getName()));
+                       else
+                               fprintf(stderr, "(unknown type)");
+               }
+               break;
+       }
+       }
+       fprintf(stderr, "\n");
+}
+
+} /* namespace gnash */

Index: server/asClass.h
===================================================================
RCS file: server/asClass.h
diff -N server/asClass.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/asClass.h    29 Sep 2007 08:24:21 -0000      1.1
@@ -0,0 +1,661 @@
+// 
+//   Copyright (C) 2007 Free Software Foundation, Inc.
+// 
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef GNASH_AS_CLASS_H
+#define GNASH_AS_CLASS_H
+
+#include <list>
+#include <map>
+#include <vector>
+#include "string_table.h"
+#include "as_value.h"
+
+namespace gnash {
+
+class as_function;
+class asNamespace;
+class asMethod;
+class asClass;
+class asException;
+class asBinding;
+class asBoundValue;
+class asBoundAccessor;
+class ClassHierarchy;
+
+class asException
+{
+public:
+       void setStart(uint32_t i) { mStart = i; }
+       void setEnd(uint32_t i) { mEnd = i; }
+       void setCatch(uint32_t i) { mCatch = i; }
+       void catchAny() { mCatchAny = true; }
+       void setCatchType(asClass* p) { mCatchType = p; }
+       void setNamespace(asNamespace* n) { mNamespace = n; }
+       void setName(string_table::key name) { mName = name; }
+
+private:
+       uint32_t mStart;
+       uint32_t mEnd;
+       uint32_t mCatch;
+       bool mCatchAny;
+       asClass *mCatchType;
+       asNamespace *mNamespace;
+       string_table::key mName;
+};
+
+/// An abstract binding for ActionScript.
+class asBinding
+{
+public:
+       void dump(string_table::key name);
+
+       void setConst() { mConst = true; }
+       void unsetConst() { mConst = false; }
+       bool isConst() { return mConst; }
+
+       void setStatic() { mStatic = true; }
+       void unsetStatic() { mStatic = false; }
+       bool isStatic() { return mStatic; }
+
+       uint32_t getSlotId() { return mSlotId; }
+       void setSlotId(uint32_t s) { mSlotId = s; }
+
+       // As a member method.
+       asBinding(asNamespace *ns, asMethod *pMethod, bool isstatic = false) :
+               mNamespace(ns), mType(T_METHOD), mSlotId(0), mConst(true),
+               mStatic(isstatic),      mMethod(pMethod)
+       {/**/}
+
+       // As an assignable function.
+       asBinding(asNamespace *ns, asMethod *pMethod, uint32_t sid, bool 
isstatic) :
+               mNamespace(ns), mType(T_METHOD), mSlotId(sid), mConst(false),
+               mStatic(isstatic),      mMethod(pMethod)
+       {/**/}
+
+       asBinding(asNamespace *ns, asBoundValue *pValue, uint32_t sid, bool 
isconstant,
+               bool isstatic) : mNamespace(ns), mType(T_VALUE), mSlotId(sid), 
mConst(isconstant),
+               mStatic(isstatic), mValue(pValue)
+       {/**/}
+
+       asBinding(asNamespace *ns, asBoundValue *pValue, uint32_t sid, bool 
isstatic) :
+               mNamespace(ns), mType(T_VALUE), mSlotId(sid), mConst(false), 
mStatic(isstatic),
+               mValue(pValue)
+       {/**/}
+
+       asBinding(asNamespace *ns, asBoundAccessor *pAccess, bool isstatic) :
+               mNamespace(ns), mType(T_ACCESS), mSlotId(0), mConst(true), 
mStatic(isstatic),
+               mAccess(pAccess)
+       {/**/}
+
+       asBinding(asNamespace *ns, asClass *pClass, uint32_t sid, bool 
isstatic) :
+               mNamespace(ns), mType(T_CLASS), mSlotId(sid), mConst(true), 
mStatic(isstatic),
+               mClass(pClass)
+       {/**/}
+
+       asBinding() : mNamespace(NULL), mType(T_CLASS), mSlotId(0), 
mConst(false), mStatic(false),
+               mClass(NULL)
+       {/**/}
+
+       void reset(asBoundAccessor *pAccess, bool isstatic)
+       {
+               mType = T_ACCESS;
+               mAccess = pAccess;
+               mConst = true;
+               mStatic = isstatic;
+       }
+
+       asBoundAccessor* getAccessor()
+       { return mType == T_ACCESS ? mAccess : NULL; }
+
+       asBoundValue* getValue()
+       { return mType == T_VALUE ? mValue : NULL; }
+
+       asMethod* getMethod()
+       { return mType == T_METHOD ? mMethod : NULL; }
+
+       asClass* getClass()
+       { return mType == T_CLASS ? mClass : NULL; }
+
+private:
+       asNamespace *mNamespace;
+
+       typedef enum
+       {
+               T_CLASS,
+               T_METHOD,
+               T_VALUE,
+               T_ACCESS
+       } types;
+       types mType;
+
+       uint32_t mSlotId;
+       bool mConst;
+       bool mStatic;
+
+       union
+       {
+               asClass *mClass;
+               asMethod *mMethod;
+               asBoundValue *mValue;
+               asBoundAccessor *mAccess;
+       };
+};
+
+class asMethodBody
+{
+public:
+       void setSize(std::size_t s) { mData.resize(s); }
+       std::size_t getSize() { return mData.size(); }
+       char *getRaw() { return &mData.front(); }
+private:
+       std::vector<char> mData;
+};
+
+/// Represent an ActionScript namespace
+class asNamespace
+{
+public:
+       void markReachableResources() const { /* TODO */ }
+
+       /// Our parent (for protected)
+       void setParent(asNamespace* p) { mParent = p; }
+
+       asNamespace* getParent() { return mParent; }
+
+       /// Set the uri
+       void setURI(string_table::key name) { mUri = name; }
+
+       /// What is the Uri of the namespace?
+       string_table::key getURI() const { return mUri; }
+
+       /// What is the XML prefix?
+       string_table::key getPrefix() const { return mPrefix; }
+
+       /// Create an empty namespace
+       asNamespace() : mParent(NULL), mUri(0), mPrefix(0), mClasses(),
+               mRecursePrevent(false), mPrivate(false), mProtected(false)
+       {/**/}
+
+       /// Add a class to the namespace. The namespace stores this, but
+       /// does not take ownership. (So don't delete it.)
+       bool addClass(string_table::key name, asClass *a)
+       {
+               if (getClassInternal(name))
+                       return false;
+               mClasses[name] = a;
+               return true;
+       }
+
+       void stubPrototype(string_table::key name);
+
+       /// Get the named class. Returns NULL if information is not known
+       /// about the class. (Stubbed classes still return NULL here.)
+       asClass *getClass(string_table::key name) 
+       {
+               if (mRecursePrevent)
+                       return NULL;
+
+               asClass *found = getClassInternal(name);
+               if (found || !getParent())
+                       return found;
+
+               mRecursePrevent = true;
+               found = getParent()->getClass(name);
+               mRecursePrevent = false;
+               return found;
+       }
+
+       void dump();
+
+       void setPrivate() { mPrivate = true; }
+       void unsetPrivate() { mPrivate = false; }
+       bool isPrivate() { return mPrivate; }
+
+       void setProtected() { mProtected = true; }
+       void unsetProtected() { mProtected = false; }
+       bool isProtected() { return mProtected; }
+       
+private:
+       asNamespace *mParent;
+       string_table::key mUri;
+       string_table::key mPrefix;
+
+       typedef std::map<string_table::key, asClass*> container;
+       container mClasses;
+       mutable bool mRecursePrevent;
+
+       bool mPrivate;
+       bool mProtected;
+
+       asClass *getClassInternal(string_table::key name) const
+       {
+               container::const_iterator i;
+               if (mClasses.empty())
+                       return NULL;
+
+               i = mClasses.find(name);
+               if (i == mClasses.end())
+                       return NULL;
+               return i->second;
+       }
+};
+
+class asBoundValue;
+class asBoundAccessor;
+
+class asBoundAccessor
+{
+public:
+       bool setGetter(asMethod *p) { mGetter = p; return true; }
+       bool setSetter(asMethod *p) { mSetter = p; return true; }
+       bool setValue(asBoundValue *p) { mValue = p; return true; }
+
+       asBoundValue* getValue() { return mValue; }
+       asMethod *getGetter() { return mGetter; }
+       asMethod *getSetter() { return mSetter; }
+
+private:
+       asMethod *mGetter;
+       asMethod *mSetter;
+       asBoundValue *mValue;
+};
+
+class asBoundValue 
+{
+public:
+       asBoundValue() : mConst(false), mValue()
+       { mValue.set_undefined(); }
+       void setValue(as_value &v) { mValue = v; }
+       as_value& getCurrentValue() { return mValue; }
+
+       void setType(asClass *t) { mType = t; }
+       asClass *getType() { return mType; }
+
+private:
+       bool mConst;
+       asClass *mType;
+       as_value mValue;
+};
+
+/// A class to represent, abstractly, an ActionScript method.
+///
+/// Methods are unnamed until they are bound to an object.
+class asMethod
+{
+private:
+       typedef enum
+       {
+               FLAGS_FINAL = 0x01,
+               FLAGS_PROTECTED = 0x02,
+               FLAGS_PUBLIC = 0x04,
+               FLAGS_PRIVATE = 0x08
+       } flags;
+       /// A list of type identifiers
+       typedef std::list<asClass*> argumentList;
+       typedef std::map<string_table::key, asBinding> binding_container;
+
+       binding_container mBindings;
+       asClass *mReturnType;
+       asClass* mOwner;
+       asMethod* mSuper;
+       int mMinArguments;
+       int mMaxArguments;
+       argumentList mArguments;
+       std::list<as_value> mOptionalArguments;
+       as_function *mImplementation;
+       unsigned char mFlags;
+       asMethodBody *mBody;
+
+       bool addBinding(string_table::key name, asBinding b)
+       { mBindings[name] = b; return true; }
+
+       asBinding *getBinding(string_table::key name)
+       {
+               binding_container::iterator i;
+               if (mBindings.empty())
+                       return NULL;
+               i = mBindings.find(name);
+               if (i == mBindings.end())
+                       return NULL;
+               return &i->second;
+       }
+
+public:
+       asMethod() : mBindings(), mReturnType(NULL),
+               mOwner(NULL), mSuper(NULL), mMinArguments(-1), 
mMaxArguments(-1),
+               mArguments(), mOptionalArguments(), mImplementation(NULL), 
mFlags(0),
+               mBody(NULL)
+       {/**/}
+
+       bool hasActivation() { return !mBindings.empty(); }
+
+       asMethodBody *getBody() { return mBody; }
+       void setBody(asMethodBody* b) { mBody = b; }
+
+       bool addValue(string_table::key name, asNamespace *ns, uint32_t slotId,
+               asClass *type, as_value& val, bool isconst, ClassHierarchy *CH);
+
+       bool addSlot(string_table::key name, asNamespace *ns, uint32_t slotId,
+               asClass *type, ClassHierarchy *CH);
+
+       bool addMethod(string_table::key name, asNamespace *ns, asMethod 
*method);
+
+       bool addGetter(string_table::key name, asNamespace *ns, asMethod 
*method,
+               ClassHierarchy *CH);
+
+       bool addSetter(string_table::key name, asNamespace *ns, asMethod 
*method,
+               ClassHierarchy *CH);
+
+       bool addMemberClass(string_table::key name, asNamespace *ns,
+               uint32_t slotId, asClass *type);
+       
+       bool addSlotFunction(string_table::key name, asNamespace *ns,
+               uint32_t slotId, asMethod *method);
+
+       /// \brief
+       /// Get the unique identifier of the owning class.
+       /// 0 indicates that no class owns this.
+       asClass* getOwner() const { return mOwner; }
+
+       /// \brief
+       /// Set the owner of this method.
+       void setOwner(asClass* s) { mOwner = s; }
+
+       /// \brief
+       /// Get the unique identifier for the return type. 0 is 'anything'.
+       /// (This is the value of any dynamic property.)
+       /// Id reference: Type
+       asClass* getReturnType() const { return mReturnType; }
+
+       /// Set the return type
+       void setReturnType(asClass* t) { mReturnType = t; }
+
+       asMethod *getSuper() { return mSuper; }
+
+       void setSuper(asMethod* s) { mSuper = s; }
+
+       /// \brief
+       /// Is the method final? If so, it may not be overridden.
+       bool isFinal() const { return mFlags & FLAGS_FINAL; }
+
+       /// \brief
+       /// Set the method as final.
+       void setFinal() { mFlags = mFlags | FLAGS_FINAL; }
+
+       /// \brief
+       /// Unset the method as final. Not final anymore.
+       void unsetFinal() { mFlags = mFlags & ~FLAGS_FINAL; }
+
+       /// \brief
+       /// Is the method private?
+       bool isPrivate() const { return mFlags & FLAGS_PRIVATE; }
+
+       /// \brief
+       /// Make the method private.
+       void setPrivate()
+       { mFlags = (mFlags & ~(FLAGS_PUBLIC | FLAGS_PROTECTED)) | 
FLAGS_PRIVATE; }
+
+       /// \brief
+       /// Is the method protected?
+       bool isProtected() const { return mFlags & FLAGS_PROTECTED; }
+
+       /// \brief
+       /// Make the method protected.
+       void setProtected()
+       { mFlags = (mFlags & ~(FLAGS_PUBLIC | FLAGS_PRIVATE)) | 
FLAGS_PROTECTED; }
+
+       /// \brief
+       /// Is the method public?
+       bool isPublic() const { return mFlags & FLAGS_PUBLIC; }
+
+       /// \brief
+       /// Make the method public.
+       void setPublic()
+       { mFlags = (mFlags & ~(FLAGS_PRIVATE | FLAGS_PROTECTED)) | 
FLAGS_PUBLIC; }
+
+       /// \brief
+       /// How many arguments are required? -1 means unknown.
+       int minArgumentCount() const { return mMinArguments; }
+
+       /// \brief
+       /// Set the required minimum arguments.
+       void setMinArgumentCount(int i) { mMinArguments = i; }
+
+       /// \brief
+       /// How many arguments are allowed? -1 means unknown.
+       int maxArgumentCount() const { return mMaxArguments; }
+
+       /// Set the required maximum arguments.
+       void setMaxArgumentCount(int i) { mMaxArguments = i; }
+
+       /// \brief
+       /// Push an argument of type t into the method definition
+       void pushArgument(asClass *t) { mArguments.push_back(t); }
+
+       /// \brief
+       /// Push an optional argument's default value.
+       void pushOptional(const as_value& v) { mOptionalArguments.push_back(v); 
}
+
+       /// \brief
+       /// Are any of the arguments optional?
+       bool optionalArguments() const
+       { return minArgumentCount() != maxArgumentCount(); }
+
+       /// \brief
+       /// Get a reference to a list of argument types.
+       argumentList& getArgumentList() { return mArguments; }
+
+       /// \brief
+       /// Get an object capable of executing this function.
+       /// Note: This may be NULL, because we might have information about this
+       /// function but not actually have it yet.
+       as_function* getImplementation() { return mImplementation; }
+
+       /// \brief
+       /// Check to see whether m could override this.
+       ///
+       /// Check to see whether m could override this. This means:
+       /// Same return type. Same parameter types. Same access. At least as 
many
+       /// default arguments. this is not final or private. Should check, but
+       /// does not for information storing reasons: they are not in the same
+       /// override chain. (Can be checked in management object.)
+       /// have a super.
+       bool isOkayAsSuper(const asMethod &m) const
+       {
+               if (mMinArguments < m.mMinArguments
+                       || m.mMaxArguments < mMaxArguments
+                       || isFinal()
+                       || mFlags != m.mFlags
+                       || isPrivate())
+                       return false;
+               for (argumentList::const_iterator i, j; /**/; ++i, ++j)
+               {
+                       if (i == mArguments.end())
+                               return (j == mArguments.end());
+                       if (j == mArguments.end())
+                               return false;
+                       if (*i != *j)
+                               return false;
+               }
+               return true;
+       }
+};
+
+/// A class to represent, abstractly, ActionScript prototypes.
+///
+/// This class is intended to be able to capture the structure of an
+/// ActionScript prototype as a type, rather than as an object. This is
+/// contrary to the spirit of ActionScript as a dynamic language, but it is
+/// incredibly helpful to an interpreter for that language.
+class asClass
+{
+public:
+       void dump();
+
+       bool addValue(string_table::key name, asNamespace *ns, uint32_t slotId,
+               asClass *type, as_value& val, bool isconst, bool isstatic,
+               ClassHierarchy *CH);
+
+       bool addSlot(string_table::key name, asNamespace *ns, uint32_t slotId,
+               asClass *type, bool isstatic, ClassHierarchy *CH);
+
+       bool addMethod(string_table::key name, asNamespace *ns, asMethod 
*method,
+               bool isstatic);
+
+       bool addGetter(string_table::key name, asNamespace *ns, asMethod 
*method,
+               bool isstatic, ClassHierarchy *CH);
+
+       bool addSetter(string_table::key name, asNamespace *ns, asMethod 
*method,
+               bool isstatic, ClassHierarchy *CH);
+
+       bool addMemberClass(string_table::key name, asNamespace *ns,
+               uint32_t slotId, asClass *type, bool isstatic);
+
+       // TODO: Figure out how this differs from addMethod
+       bool addSlotFunction(string_table::key name, asNamespace *ns,
+               uint32_t slotId, asMethod *method, bool isstatic);
+
+       /// Is the class final?
+       bool isFinal() const { return mFinal; }
+
+       /// Set the class as final.
+       void setFinal() { mFinal = true; }
+
+       /// Set the class as not final.
+       void unsetFinal() { mFinal = false; }
+
+       /// Is the class sealed?
+       bool isSealed() const { return mSealed; }
+
+       /// Set the class as sealed.
+       void setSealed() { mSealed = true; }
+
+       // Set the class as not sealed.
+       void unsetSealed() { mSealed = false; }
+
+       /// Is the class an interface type?
+       bool isInterface() const { return mInterface; }
+
+       /// Set the class as an interface.
+       void setInterface() { mInterface = true; }
+
+       /// Set the class as not an interface.
+       void unsetInterface() { mInterface = false; }
+
+       /// Is the class dynamic?
+       bool isDynamic() const { return mDynamic; }
+
+       /// Set the class as dynamic.
+       void setDynamic() { mDynamic = true; }
+
+       /// Set the class as not dynamic.
+       void unsetDynamic() { mDynamic = false; }
+
+       /// Does the class have a protected namespace to be inherited?
+       bool hasProtectedNs() const { return mProtectedNs != NULL; }
+
+       /// Get the protected namespace.
+       asNamespace *getProtectedNs() { return mProtectedNs; }
+
+       /// Set the protected namespace.
+       void setProtectedNs(asNamespace *n) { mProtectedNs = n; }
+
+       string_table::key getName() const { return mName; }
+
+       /// Set our Name
+       void setName(string_table::key name) { mName = name; }
+
+       /// What is the type of our parent class?
+       asClass* getSuper() const { return mSuper; }
+
+       /// We implement this interface.
+       void pushInterface(asClass* p) { mInterfaces.push_back(p); }
+
+       /// This is our constructor.
+       void setConstructor(asMethod *m) { mConstructor = m; }
+
+       void setStaticConstructor(asMethod *m) { mStaticConstructor = m; }
+
+       void setSuper(asClass *p) { mSuper = p; }
+
+       void setDeclared() { mDeclared = true; }
+       bool isDeclared() { return mDeclared; }
+       void setInherited() { mInherited = true; }
+       bool isInherited() { return mInherited; }
+
+       void setSystem() { mSystem = true; }
+       void unsetSystem() { mSystem = false; }
+       bool isSystem() { return mSystem; }
+
+       asClass() : mFinal(false), mSealed(false), mDynamic(false),
+               mInterface(false), mName(0), mInterfaces(), mProtectedNs(NULL),
+               mSuper(NULL), mConstructor(NULL), mStaticConstructor(NULL),
+               mBindings(), mStaticBindings(), mDeclared(false), 
mInherited(false),
+               mSystem(false)
+       {/**/}
+
+private:
+       bool addBinding(string_table::key name, asBinding b)
+       { mBindings[name] = b; return true; }
+       bool addStaticBinding(string_table::key name, asBinding b)
+       { mStaticBindings[name] = b; return true; }
+
+       asBinding *getStaticBinding(string_table::key name)
+       {
+               binding_container::iterator i;
+               if (mStaticBindings.empty())
+                       return NULL;
+               i = mStaticBindings.find(name);
+               if (i == mStaticBindings.end())
+                       return NULL;
+               return &i->second;
+       }
+
+       asBinding *getBinding(string_table::key name)
+       {
+               binding_container::iterator i;
+               if (mBindings.empty())
+                       return NULL;
+               i = mBindings.find(name);
+               if (i == mBindings.end())
+                       return NULL;
+               return &i->second;
+       }
+
+       bool mFinal;
+       bool mSealed;
+       bool mDynamic;
+       bool mInterface;
+       string_table::key mName;
+       std::list<asClass*> mInterfaces;
+       asNamespace *mProtectedNs;
+       asClass *mSuper;
+       asMethod *mConstructor;
+       asMethod *mStaticConstructor;
+
+       typedef std::map<string_table::key, asBinding> binding_container;
+
+       binding_container mBindings;
+       binding_container mStaticBindings;
+       bool mDeclared;
+       bool mInherited;
+       bool mSystem;
+};
+
+} /* namespace gnash */
+
+#endif /* GNASH_AS_CLASS_H */




reply via email to

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