gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/vm/Machine.h server/vm/M...


From: Chad Musick
Subject: [Gnash-commit] gnash ChangeLog server/vm/Machine.h server/vm/M...
Date: Tue, 09 Oct 2007 16:21:38 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Chad Musick <cmusick>   07/10/09 16:21:37

Modified files:
        .              : ChangeLog 
        server/vm      : Machine.h 
Added files:
        server/vm      : Machine.cpp 
Removed files:
        server/vm      : AbcHandlers.cpp 

Log message:
        Rename AbcHandlers.cpp to Machine.cpp, more work on this file.
        More work on Machine.h

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4578&r2=1.4579
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/Machine.h?cvsroot=gnash&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/Machine.cpp?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/AbcHandlers.cpp?cvsroot=gnash&r1=1.5&r2=0

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4578
retrieving revision 1.4579
diff -u -b -r1.4578 -r1.4579
--- ChangeLog   9 Oct 2007 16:17:39 -0000       1.4578
+++ ChangeLog   9 Oct 2007 16:21:37 -0000       1.4579
@@ -1,6 +1,9 @@
 2007-10-10 Chad Musick <address@hidden>
 
        * server/vm/SafeStack.h: Remove limit on size of grow()
+       * server/vm/Machine.cpp: Name changed from server/vm/AbcHandlers.cpp,
+         more work on making it work.
+       * server/vm/Machine.h: More work on making it work.
 
 2007-10-09 Sandro Santilli <address@hidden>
 

Index: server/vm/Machine.h
===================================================================
RCS file: /sources/gnash/gnash/server/vm/Machine.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- server/vm/Machine.h 8 Oct 2007 06:55:11 -0000       1.3
+++ server/vm/Machine.h 9 Oct 2007 16:21:37 -0000       1.4
@@ -21,9 +21,36 @@
 
 #include "SafeStack.h"
 #include "as_value.h"
+#include "asClass.h"
+#include "swf.h"
 
 namespace gnash {
 
+class character;
+class as_object;
+
+class asScope
+{
+public:
+       void setBase(asScope *);
+};
+
+class asName
+{
+public:
+       asName(uint32_t);
+       asName();
+       void makeComplete();
+
+       bool isRuntime();
+       bool isRtns();
+
+       void fill(as_object*);
+       void setNamespace(as_value&);
+
+       uint32_t id;
+};
+
 /// This machine is intended to work without relying on the C++ call stack,
 /// by resetting its Stream and Stack members (actually, by limiting the stack)
 /// to make function calls, rather than calling them directly in C++.
@@ -65,7 +92,7 @@
        /// @return
        /// The number of stack elements used by the name.
        /// At present, always 0, 1, or 2. These are not dropped.
-       int completeName(asBoundName& name, int initial = 0);
+       int completeName(asName& name, int initial = 0);
 
        /// Given a value v, find the class object of the superclass of v.
        ///
@@ -73,7 +100,7 @@
        /// The object whose superclass is desired.
        ///
        /// @param find_primitive
-       /// If true, the ActionScript prototype will be find for primitive 
values.
+       /// If true, the ActionScript prototype will be found for primitive 
values.
        ///
        /// @return
        /// Null if the superclass was not found, or the superclass.
@@ -95,7 +122,7 @@
        /// This returns the value, but on the stack.
        /// (Since the return value is not known until after control has left
        /// the caller of this, it's impossible to return a meaningful value.
-       void getMember(asClass* pDefinition, asBoundName& name, as_value& 
source);
+       void getMember(asClass* pDefinition, asName& name, as_value& source);
 
        /// Set a member in an object.
        ///
@@ -113,7 +140,7 @@
        ///
        /// @return
        /// Nothing.
-       void setMember(asClass*, asBoundName&, as_value& target, as_value& val);
+       void setMember(asClass*, asName&, as_value& target, as_value& val);
 
        std::string& pool_string(uint32_t);
        int pool_int(uint32_t);
@@ -121,15 +148,15 @@
        double pool_double(uint32_t);
        asNamespace* pool_namespace(uint32_t);
        asMethod* pool_method(uint32_t);
+       asClass* pool_class(uint32_t);
+       asName* pool_name(uint32_t);
 
-       as_value findProperty(asBoundName&);
+       asBinding* findProperty(asName&);
 
        void pushScope(asScope*);
        asScope* popScope();
 
-       void execute_as3();
-
-       void execute_as2();
+       void execute();
 
        /// push a function call to be executed next.
        ///
@@ -153,8 +180,10 @@
        /// @param pBind
        /// The non-null binding.  If this is only a partial binding, then
        /// the 'this' value will be used to complete it, when possible.
-       void pushCall(unsigned int stack_in, unsigned int stack_out,
-               as_value &return_slot, asBinding *pBind);
+       void pushCall(unsigned int stack_in, as_value *return_slot,
+               asBinding *pBind);
+
+       Machine(string_table &ST, ClassHierarchy *CH);
 
 private:
        /// The state of the machine.
@@ -168,15 +197,16 @@
                CodeStream *mStream;
                asNamespace *mDefaultXMLNamespace;
                asScope *mCurrentScope;
-               asValue *mGlobalReturn;
+               as_value *mGlobalReturn;
        };
 
        void saveState();
        void restoreState();
 
-       Stack<as_value> mStack;
-       Stack<State> mStateStack;
-       Stack<asScope> mScopeStack;
+       SafeStack<as_value> mStack;
+       SafeStack<State> mStateStack;
+       SafeStack<asScope> mScopeStack;
+       SafeStack<as_value> mFrame;
        CodeStream *mStream;
 
        ClassHierarchy *mCH;
@@ -186,8 +216,10 @@
        asScope *mGlobalScope;
        asScope *mCurrentScope;
 
-       asValue *mGlobalReturn;
-       asValue mIgnoreReturn; // Throw away returns go here.
+       as_value *mGlobalReturn;
+       as_value mIgnoreReturn; // Throw away returns go here.
+
+       bool mIsAS3; // Is the stream an AS3 stream.
 };
 
 } // namespace gnash

Index: server/vm/Machine.cpp
===================================================================
RCS file: server/vm/Machine.cpp
diff -N server/vm/Machine.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/vm/Machine.cpp       9 Oct 2007 16:21:37 -0000       1.1
@@ -0,0 +1,2320 @@
+//
+//   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 "Machine.h"
+#include "as_object.h"
+#include "ClassHierarchy.h"
+#include "namedStrings.h"
+#include "array.h"
+
+namespace gnash {
+
+/// ENSURE_NUMBER makes sure that the given argument is a number,
+/// calling the valueOf method if necessary -- it's a macro so that
+/// the valueOf method may be pushed if needed, and then whatever
+/// opcode asked for this will be re-entered.
+#define ENSURE_NUMBER(vte)                                                     
                                        \
+{                                                                              
                                                                \
+       as_value *e = &vte;                                                     
                                                \
+       if (e->is_object())                                                     
                                                \
+       {                                                                       
                                                                \
+               asBinding *b = e->to_object()->getBinding(NSV::PROP_VALUE_OF);  
\
+               if (b)                                                          
                                                        \
+               {                                                               
                                                                \
+                       mStream->seekTo(opStart);                               
                                        \
+                       mStack.push(*e);                                        
                                                \
+                       pushCall(1, e, b);                                      
                                                \
+                       break;                                                  
                                                        \
+               }                                                               
                                                                \
+       }                                                                       
                                                                \
+}                                                                              
           /* end of ENSURE_NUMBER */
+
+/// ENSURE_OBJECT will throw an exception if the argument isn't an
+/// object. It's a macro to match with the other ENSURE_ macros.
+#define ENSURE_OBJECT(vte)                                                     
                                        \
+{                                                                              
                                                                \
+       if (!vte.is_object())                                                   
                                        \
+               throw ASException();                                            
                                        \
+}                                                                              
           /* end of ENSURE_OBJECT */
+
+/// ENSURE_STRING makes sure that the given argument is a string,
+/// calling the toString method if necessary -- it's a macro so that
+/// the toString may be pushed if needed, and then whatever opcode
+/// asked for this will be re-entered.
+#define ENSURE_STRING(vte)                                                     
                                        \
+{                                                                              
                                                                \
+       as_value *c = &vte; /* Don't call vte multiple times */                 
        \
+       if (c->is_object())                                                     
                                                \
+       {                                                                       
                                                                \
+               asBinding *d = c->to_object()->getBinding(NSV::PROP_TO_STRING); 
\
+               if (d)                                                          
                                                        \
+               {                                                               
                                                                \
+                       mStream->seekTo(opStart);                               
                                        \
+                       mStack.push(*c);                                        
                                                \
+                       pushCall(1, c, d);                                      
                                                \
+                       break;                                                  
                                                        \
+               }                                                               
                                                                \
+       }                                                                       
                                                                \
+}                                                                              
           /* end of ENSURE_STRING */
+
+/// ABSTRACT_COMPARE is the abstract comparison as described in the ECMA
+/// standard.  The 'truth_of_undefined' is used to specify which value
+/// should be set for NaN values. It's a macro so that calls may be
+/// pushed in the ENSURE_STRING and ENSURE_NUMBER macros.
+#define ABSTRACT_COMPARE(store, rv1, rv2, truth_of_undefined)                  
\
+{                                                                              
                                                                \
+       as_value &a = rv1; /* Don't call rv1 multiple times */                  
        \
+       as_value &b = rv2; /* Don't call rv2 multiple times */                  
        \
+       if (a.ptype() == PTYPE_STRING && b.ptype() == PTYPE_STRING)             
\
+       {                                                                       
                                                                \
+               ENSURE_STRING(a);                                               
                                                \
+               ENSURE_STRING(b);                                               
                                                \
+               store = a.to_string() < b.to_string();                          
                        \
+       }                                                                       
                                                                \
+       else                                                                    
                                                        \
+       {                                                                       
                                                                \
+               ENSURE_NUMBER(a);                                               
                                                \
+               ENSURE_NUMBER(b);                                               
                                                \
+               double ad = a.to_number(); double bd = b.to_number();           
        \
+               if (isnan(ad) || isnan(bd))                                     
                                        \
+                       store = truth_of_undefined;                             
                                \
+               else if (isinf(ad) && ad > 0)                                   
                                \
+                       store = false;                                          
                                                \
+               else if (isinf(bd) && bd > 0)                                   
                                \
+                       store = true;                                           
                                                \
+               else if (isinf(bd) && bd < 0)                                   
                                \
+                       store = false;                                          
                                                \
+               else if (isinf(ad) && ad < 0)                                   
                                \
+                       store = true;                                           
                                                \
+               else                                                            
                                                        \
+                       store = ad < bd;                                        
                                                \
+       }                                                                       
                                                                \
+}                                                                              
        /* end of ABSTRACT_COMPARE */
+
+#define ABSTRACT_EQUALITY(st, ev1, ev2, strictness_on)                         
        \
+{                                                                              
                                                                \
+       bool *store = &st;                                                      
                                                \
+       as_value &a = ev1; /* Don't call ev1 multiple times */                  
        \
+       as_value &b = ev2; /* Don't call ev2 multiple times */                  
        \
+       if (a.is_object() && b.is_object())                                     
                                \
+               *store = a.to_object() == b.to_object();                        
                        \
+       else if (a.is_object() || b.is_object())                                
                        \
+               *store = false;                                                 
                                                \
+       else if (a.ptype() != b.ptype())                                        
                                \
+       {                                                                       
                                                                \
+               if (!strictness_on && (a.is_undefined() || b.is_undefined()) && 
\
+                       (a.is_null() || b.is_null()))                           
                                \
+                       *store = true;                                          
                                                \
+               else                                                            
                                                        \
+                       *store = false;                                         
                                                \
+       }                                                                       
                                                                \
+       else if (a.is_number())                                                 
                                        \
+       {                                                                       
                                                                \
+               double ad = a.to_number(); double bd = b.to_number();           
        \
+               if (isnan(ad) || isnan(bd))                                     
                                        \
+                       *store = false;                                         
                                                \
+               else if (isinf(ad) && ad > 0)                                   
                                \
+                       *store = (isinf(bd) && bd > 0);                         
                                \
+               else if (isinf(ad) && ad < 0)                                   
                                \
+                       *store = (isinf(bd) && bd < 0);                         
                                \
+               else                                                            
                                                        \
+                       *store = (ad == bd);                                    
                                        \
+       }                                                                       
                                                                \
+       else if (a.is_bool() && b.is_bool())                                    
                        \
+               *store = a.to_bool() == b.to_bool();                            
                        \
+       else                                                                    
                                                        \
+               *store = false;                                                 
                                                \
+}                                                                              
   /* end of ABSTRACT_EQUALITY */
+
+#define JUMPIF(jtruth)                                                         
                                        \
+{                                                                              
                                                                \
+       int32_t jumpOffset = mStream->read_S24();                               
                        \
+       if (jtruth)                                                             
                                                        \
+               mStream->seekBy(jumpOffset);                                    
                                \
+       break;                                                                  
                                                        \
+}                                                                              
                          /* end of JUMPIF */
+
+/// The type of exceptions thrown by ActionScript.
+class ASException
+{
+public:
+       as_value mValue;
+
+       ASException(as_value &v) { mValue = v; }
+       ASException() { mValue.set_undefined(); }
+};
+
+class ASReferenceError : public ASException
+{
+public:
+       ASReferenceError() : ASException()
+       {/**/}
+};
+
+class ASTypeError : public ASException
+{
+public:
+       ASTypeError() : ASException()
+       {/**/}
+};
+
+void
+Machine::execute()
+{
+       uint8_t opcode;
+
+       for ( ; ; )
+       {
+               std::size_t opStart = mStream->tell();
+
+       if (mIsAS3)
+       {
+       switch ((opcode = mStream->read_as3op())) // Assignment intentional
+       {
+       default:
+               throw ASException();
+       case 0:
+       {
+// This is not actually an opcode -- it occurs when the stream is
+// empty. We may need to return from a function, or we may be done.
+               break;
+       }
+/// 0x01 ABC_ACTION_BKPT
+/// Do: Enter the debugger if one has been invoked.
+/// This is a no-op. Enable it if desired.
+/// 0x02 ABC_ACTION_NOP
+/// Do: Nothing.
+/// 0xF3 ABC_ACTION_TIMESTAMP
+       case SWF::ABC_ACTION_NOP:
+       case SWF::ABC_ACTION_BKPT:
+       case SWF::ABC_ACTION_TIMESTAMP:
+       {
+               break;
+       }
+/// 0x03 ABC_ACTION_THROW
+/// Stack In:
+///  obj -- an object
+/// Stack Out:
+///  .
+/// Do: Throw obj as an exception
+/// Equivalent: ACTIONTHROW
+       case SWF::ABC_ACTION_THROW:
+       {
+               throw ASException(mStack.pop());
+               break;
+       }
+/// 0x04 ABC_ACTION_GETSUPER
+/// Stream:
+///  name_id -- V32 index to multiname 'name'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff.
+///  obj -- an object
+/// Stack Out:
+///  obj.super.name
+///  May be the same as the value of obj.name (E.g. inherited variables)
+       case SWF::ABC_ACTION_GETSUPER:
+       {
+               // Get the name.
+               asName a = mStream->read_V32();
+               // Finish it, if necessary.
+               mStack.drop(completeName(a));
+               // Get the target object.
+               as_value& vobj = mStack.top(0);
+               asClass *pClass = findSuper(vobj, true);
+               // If we don't have a class yet, throw.
+               if (!pClass)
+                       throw ASReferenceError();
+               asBinding *b = pClass->getGetBinding(vobj, a);
+               // The object is on the top already.
+               pushCall(1, &mStack.top(0), b);
+               break;
+       }
+/// 0x05 ABC_ACTION_SETSUPER
+/// Stream: UV32 index to multiname 'name'
+/// Stack In:
+///  val -- an object
+///  [ns [n]] -- Namespace stuff.
+///  obj -- an object
+/// Stack Out:
+///  .
+/// Do: Set obj.super.name to val, if allowable.
+       case SWF::ABC_ACTION_SETSUPER:
+       {
+               // Get and finish the name.
+               asName a = mStream->read_V32();
+               as_value vobj = mStack.pop(); // The value
+
+               mStack.drop(completeName(a));
+
+               as_value target = mStack.pop();
+               asClass *pClass = findSuper(target, true);
+               if (!pClass)
+                       throw ASReferenceError();
+               asBinding* b = pClass->getSetBinding(vobj, a);
+               // The object is on the top already.
+               pushCall(1, &mStack.top(0), b);
+               break;
+       }
+/// 0x06 ABC_ACTION_DXNS
+/// Default XML Namespace
+/// Stream: UV32 index to string pool 'nsname'
+/// Do: Create a new public namespace with name nsname, and make this the
+///  default XML namespace. 
+       case SWF::ABC_ACTION_DXNS:
+       {
+               uint32_t soffset = mStream->read_V32();
+               std::string& uri = pool_string(soffset);
+               mDefaultXMLNamespace = mCH->anonNamespace(mST.find(uri));
+               break;
+       }
+/// 0x07 ABC_ACTION_DXNSLATE
+/// Stack In:
+///  nsname -- a string object
+/// Stack Out:
+///  .
+/// Do: Same as ABC_ACTION_DXNS, but the uri is in the stack, not the stream.
+       case SWF::ABC_ACTION_DXNSLATE:
+       {
+               ENSURE_STRING(mStack.top(0));
+               const std::string& uri = mStack.top(0).to_string();
+               mDefaultXMLNamespace = mCH->anonNamespace(mST.find(uri));
+               mStack.drop(1);
+               break;
+       }
+/// 0x08 ABC_ACTION_KILL
+/// Stream: UV32 frame pointer offset 'offset'
+/// Frame: 
+///  Kill at offset
+/// Equivalent: ACTION_DELETE
+       case SWF::ABC_ACTION_KILL:
+       {
+               uint32_t regNum = mStream->read_V32();
+               mFrame.value(regNum).set_undefined();
+               break;
+       }
+/// 0x09 ABC_ACTION_LABEL
+/// Do: Unknown purpose, Tamarin does nothing.
+       case SWF::ABC_ACTION_LABEL:
+       {
+               break;
+       }
+/// 0x0C ABC_ACTION_IFNLT
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If !(a < b) move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFNLT:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), false);
+               mStack.drop(2);
+               JUMPIF(!truth); // truth is: a < b
+               break;
+       }
+/// 0x0D ABC_ACTION_IFNLE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If !(a <= b) move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFNLE:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), true);
+               mStack.drop(2);
+               JUMPIF(truth); // truth is: b < a
+               break;
+       }
+/// 0x0E ABC_ACTION_IFNGT
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If !(a > b) move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFNGT:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), false);
+               mStack.drop(2);
+               JUMPIF(!truth); // truth is: b < a
+               break;
+       }
+/// 0x0F ABC_ACTION_IFNGE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  a -- an object
+///  b -- an object
+/// Stack Out:
+///  .
+/// Do: If !(a >= b) move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFNGE:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), true);
+               mStack.drop(2);
+               JUMPIF(truth); // truth is: a < b
+               break;
+       }
+/// 0x10 ABC_ACTION_JUMP
+/// Stream: S24 jump offset 'jump'
+/// Do: If jump is negative, check for interrupts. Move by jump in stream.
+/// Equivalent: ACTION_BRANCHALWAYS
+       case SWF::ABC_ACTION_JUMP:
+       {
+               JUMPIF(true);
+               break;
+       }
+/// 0x11 ABC_ACTION_IFTRUE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a is 'true', move by jump in stream, as ABC_ACTION_JUMP does.
+/// Equivalent: ACTION_BRANCHIFTRUE
+       case SWF::ABC_ACTION_IFTRUE:
+       {
+               bool truth = mStack.top(0).to_bool();
+               mStack.drop(1);
+               JUMPIF(truth);
+               break;
+       }
+/// 0x12 ABC_ACTION_IFFALSE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a is 'false', move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFFALSE:
+       {
+               bool truth = mStack.top(0).to_bool();
+               mStack.drop(1);
+               JUMPIF(!truth);
+               break;
+       }
+/// 0x13 ABC_ACTION_IFEQ
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a == b (weakly), move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFEQ:
+       {
+               bool truth;
+               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), false);
+               mStack.drop(2);
+               JUMPIF(truth);
+               break;
+       }
+/// 0x14 ABC_ACTION_IFNE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a != b (weakly), move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFNE:
+       {
+               bool truth;
+               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), false);
+               mStack.drop(2);
+               JUMPIF(!truth);
+               break;
+       }
+/// 0x15 ABC_ACTION_IFLT
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a < b move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFLT:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), false);
+               mStack.drop(2);
+               JUMPIF(truth); // truth is: a < b
+               break;
+       }
+/// 0x16 ABC_ACTION_IFLE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a <= b move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFLE:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), true);
+               mStack.drop(2);
+               JUMPIF(!truth); // truth is: b < a
+               break;
+       }
+/// 0x17 ABC_ACTION_IFGT
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a > b move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFGT:
+       {
+               bool truth;
+               // If b < a, then a > b, with undefined as false
+               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), false);
+               mStack.drop(2);
+               JUMPIF(truth); // truth is: b < a
+               break;
+       }
+/// 0x18 ABC_ACTION_IFGE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a >= b move by jump in stream, as ABC_ACTION_JUMP does.
+       case SWF::ABC_ACTION_IFGE:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), true);
+               mStack.drop(2);
+               JUMPIF(!truth); // truth is: a < b
+               break;
+       }
+/// 0x19 ABC_ACTION_IFSTRICTEQ
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a == b (strictly), move by jump in stream, as ABC_ACTION_JUMP
+       case SWF::ABC_ACTION_IFSTRICTEQ:
+       {
+               bool truth;
+               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), true);
+               mStack.drop(2);
+               JUMPIF(truth);
+               break;
+       }
+/// 0x1A ABC_ACTION_IFSTRICTNE
+/// Stream: S24 jump offset 'jump'
+/// Stack In:
+///  b -- an object
+///  a -- an object
+/// Stack Out:
+///  .
+/// Do: If a != b (strongly), move by jump in stream, as ABC_ACTION_JUMP
+       case SWF::ABC_ACTION_IFSTRICTNE:
+       {
+               bool truth;
+               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), true);
+               mStack.drop(2);
+               JUMPIF(!truth);
+               break;
+       }
+/// 0x18 ABC_ACTION_LOOKUPSWITCH
+/// Stream: 3 bytes | V32 count as 'case_count - 1' | case_count of S24
+///  as 'cases'
+/// Stack In:
+///  index -- an integer object
+/// Stack Out:
+///  .
+/// Do: If index >= case_count, reset stream to position on op entry.
+///  Otherwise, move by cases[index] - 1 from stream position on op entry.
+       case SWF::ABC_ACTION_LOOKUPSWITCH:
+       {
+               std::size_t npos = mStream->tell();
+               if (!mStack.top(0).is_number())
+                       throw ASException();
+
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               mStack.drop(1);
+
+               mStream->seekBy(3); // Skip the intial offset.
+               uint32_t cases = mStream->read_V32();
+               // Read from our original position and use it to skip if the 
case
+               // is out of range.
+               if (index > cases)
+               {
+                       mStream->seekTo(npos);
+                       mStream->seekTo(npos + mStream->read_S24());
+               }
+               else
+               {
+                       mStream->seekTo(npos + 3 * (index + 1));
+                       uint32_t newpos = mStream->read_S24();
+                       mStream->seekTo(npos - 1 + newpos);
+               }
+               break;
+       }
+/// 0x1C ABC_ACTION_PUSHWITH
+/// Stack In:
+///  scope -- a scope
+/// Stack Out:
+///  .
+/// Do: Enter scope with previous scope as its base, unless it already had
+///  a base, in which case leave that alone.
+       case SWF::ABC_ACTION_PUSHWITH:
+       {
+               asScope a = mStack.top(0).to_scope();
+               mStack.drop(1);
+               mScopeStack.push(a);
+               // If there wasn't a base scope, then this becomes it.
+               a.setBase(mCurrentScope);
+               break;
+       }
+/// 0x1D ABC_ACTION_POPSCOPE
+/// Do: exit current scope. Clear the base if the depth is now 
+///  shallower than the base's depth.
+       case SWF::ABC_ACTION_POPSCOPE:
+       {
+               mScopeStack.pop();
+               break;
+       }
+/// 0x1E ABC_ACTION_NEXTNAME
+/// Stack In:
+///  index -- an integer object
+///  obj -- an object
+/// Stack Out:
+///  name -- the key name of the property at index in obj
+       case SWF::ABC_ACTION_NEXTNAME:
+       {
+               ENSURE_NUMBER(mStack.top(0));
+               ENSURE_OBJECT(mStack.top(1));
+               as_object *obj = mStack.top(1).to_object().get();
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               mStack.drop(1);
+               asBinding *b = obj->bindingAtIndex(index);
+               if (b)
+                       mStack.top(0) = b->getNameString();
+               else
+                       mStack.top(0) = "";
+               break;
+       }
+/// 0x1F ABC_ACTION_HASNEXT
+/// Stack In:
+///  index -- an integer object
+///  obj -- an object
+/// Stack Out:
+///  next_index -- next index after index in obj, or 0 if none.
+/// Do: If there is a key/val pair after index, make next_index as it.
+///  Otherwise, make next_index 0.
+       case SWF::ABC_ACTION_HASNEXT:
+       {
+               ENSURE_NUMBER(mStack.top(0));
+               ENSURE_OBJECT(mStack.top(1));
+               as_object *obj = mStack.top(1).to_object().get();
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               mStack.drop(1);
+               asBinding *next = obj->bindingAfterIndex(index);
+               if (next)
+                       mStack.top(0) = next->getDispatch();
+               else
+                       mStack.top(0) = 0;
+               break;
+       }
+/// 0x20 ABC_ACTION_PUSHNULL
+/// Stack Out:
+///  n -- a Null object.
+       case SWF::ABC_ACTION_PUSHNULL:
+       {
+               mStack.grow(1);
+               mStack.top(0).set_null();
+               break;
+       }
+/// 0x21 ABC_ACTION_PUSHUNDEFINED
+/// Stack Out:
+///  n -- an Undefined object.
+       case SWF::ABC_ACTION_PUSHUNDEFINED:
+       {
+               mStack.grow(1);
+               mStack.top(0).set_undefined();
+               break;
+       }
+/// 0x23 ABC_ACTION_NEXTVALUE
+/// Stack In:
+///  index -- an integer object
+///  obj -- an object (namespaces okay)
+/// Stack Out:
+///  value -- the value of the key value pair in obj at index.
+       case SWF::ABC_ACTION_NEXTVALUE:
+       {
+               ENSURE_NUMBER(mStack.top(0));
+               ENSURE_OBJECT(mStack.top(1));
+               as_object *obj = mStack.top(1).to_object().get();
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               asBinding *b = obj->bindingAtIndex(index);
+               mStack.drop(1);
+               if (!b)
+                       mStack.top(0).set_undefined();
+               else // The top of the stack is obj, as it should be.
+                       pushCall(1, &mStack.top(0), b);
+               break;
+       }
+/// 0x24 ABC_ACTION_PUSHBYTE
+/// Stream: S8 as 'byte'
+/// Stack Out:
+///  byte -- as a raw byte
+       case SWF::ABC_ACTION_PUSHBYTE:
+       {
+               int8_t b = mStream->read_s8();
+               mStack.grow(1);
+               mStack.top(0) = b;
+               break;
+       }
+/// 0x25 ABC_ACTION_PUSHSHORT
+/// Stream: V32 as 'value'
+/// Stack Out:
+///  value -- as a raw integer
+       case SWF::ABC_ACTION_PUSHSHORT:
+       {
+               signed short s = static_cast<signed short>(mStream->read_V32());
+               mStack.grow(1);
+               mStack.top(0) = s;
+               break;
+       }
+/// 0x26 ABC_ACTION_PUSHTRUE
+/// Stack Out:
+///  true -- the True object
+       case SWF::ABC_ACTION_PUSHTRUE:
+       {
+               mStack.grow(1);
+               mStack.top(0).set_bool(true);
+               break;
+       }
+/// 0x27 ABC_ACTION_PUSHFALSE
+/// Stack Out:
+///  false -- the False object
+       case SWF::ABC_ACTION_PUSHFALSE:
+       {
+               mStack.grow(1);
+               mStack.top(0).set_bool(false);
+               break;
+       }
+/// 0x28 ABC_ACTION_PUSHNAN
+/// Stack Out:
+///  NaN -- the NaN object
+       case SWF::ABC_ACTION_PUSHNAN:
+       {
+               mStack.grow(1);
+               mStack.top(0).set_nan();
+               break;
+       }
+/// 0x29 ABC_ACTION_POP
+/// Stack In:
+///  a -- anything
+/// Stack Out:
+///  .
+       case SWF::ABC_ACTION_POP:
+       {
+               mStack.drop(1);
+               break;
+       }
+/// 0x2A ABC_ACTION_DUP
+/// Stack In:
+///  a -- anything
+/// Stack Out:
+///  a
+///  a
+       case SWF::ABC_ACTION_DUP:
+       {
+               mStack.grow(1);
+               mStack.top(0) = mStack.top(1);
+               break;
+       }
+/// 0x2B ABC_ACTION_SWAP
+/// Stack In:
+///  a -- anything
+///  b -- anything
+/// Stack Out:
+///  b
+///  a
+       case SWF::ABC_ACTION_SWAP:
+       {
+               as_value inter = mStack.top(0);
+               mStack.top(0) = mStack.top(1);
+               mStack.top(1) = inter;
+               break;
+       }
+/// 0x2C ABC_ACTION_PUSHSTRING
+/// Stream: V32 string pool index 'index'
+/// Stack Out:
+///  value -- String object from string_pool[index]
+       case SWF::ABC_ACTION_PUSHSTRING:
+       {
+               mStack.grow(1);
+               mStack.top(0) = pool_string(mStream->read_V32());
+               break;
+       }
+/// 0x2D ABC_ACTION_PUSHINT
+/// Stream: V32 int pool index 'index'
+/// Stack Out:
+///  value -- Integer object from integer_pool[index]
+       case SWF::ABC_ACTION_PUSHINT:
+       {
+               mStack.grow(1);
+               mStack.top(0) = pool_int(mStream->read_V32());
+               break;
+       }
+/// 0x2E ABC_ACTION_PUSHUINT
+/// Stream: V32 uint pool index 'index'
+/// Stack Out:
+///  value -- Unsigned Integer object from unsigned_integer_pool[index]
+       case SWF::ABC_ACTION_PUSHUINT:
+       {
+               mStack.grow(1);
+               mStack.top(0) = pool_uint(mStream->read_V32());
+               break;
+       }
+/// 0x2F ABC_ACTION_PUSHDOUBLE
+/// Stream: V32 double pool index 'index'
+/// Stack Out:
+///  value -- Double object from double_pool[index]
+       case SWF::ABC_ACTION_PUSHDOUBLE:
+       {
+               mStack.grow(1);
+               mStack.top(0) = pool_double(mStream->read_V32());
+               break;
+       }
+/// 0x30 ABC_ACTION_PUSHSCOPE
+/// Stack In:
+///  scope -- a scope
+/// Stack Out:
+///  .
+/// Do: Enter scope without altering base.
+       case SWF::ABC_ACTION_PUSHSCOPE:
+       {
+               asScope a = mStack.top(0).to_scope();
+               mStack.drop(1);
+               a.setBase(mCurrentScope);
+               mScopeStack.push(a);
+               break;
+       }
+/// 0x31 ABC_ACTION_PUSHNAMESPACE
+/// Stream: V32 namespace pool index 'index'
+/// Stack Out:
+///  ns -- Namespace object from namespace_pool[index]
+       case SWF::ABC_ACTION_PUSHNAMESPACE:
+       {
+               asNamespace *ns = pool_namespace(mStream->read_V32());
+               mStack.grow(1);
+               mStack.top(0) = *ns;
+               break;
+       }
+/// 0x32 ABC_ACTION_HASNEXT2
+/// Stream: V32 frame location 'objloc' | V32 frame location 'indexloc'
+/// Stack Out:
+///  truth -- True if frame[objloc] has key/val pair after frame[indexloc],
+///   following delagates (__proto__) objects if needed. False, otherwise.
+/// Frame:
+///  Change at objloc to object which possessed next value.
+///  Change at indexloc to index (as object) of the next value.
+       case SWF::ABC_ACTION_HASNEXT2:
+       {
+               int32_t oindex = mStream->read_V32();
+               int32_t iindex = mStream->read_V32();
+               as_value &objv = mFrame.value(oindex);
+               as_value &indexv = mFrame.value(iindex);
+               ENSURE_OBJECT(objv);
+               ENSURE_NUMBER(indexv);
+               as_object *obj = objv.to_object().get();
+               uint32_t index = indexv.to_number<uint32_t>();
+               asBinding *next = obj->bindingAfterIndex(index);
+               mStack.grow(1);
+               if (next)
+               {
+                       mStack.top(0).set_bool(true);
+                       mFrame.value(oindex) = next->getOwner();
+                       mFrame.value(iindex) = next->getDispatch();
+               }
+               else
+               {
+                       mStack.top(0).set_bool(false);
+                       mFrame.value(oindex).set_null();
+                       mFrame.value(iindex) = 0;
+               }
+               break;
+       }
+/// 0x40 ABC_ACTION_NEWFUNCTION
+/// Stream: V32 'index'
+/// Stack Out:
+///  func -- the function object
+/// Do: Information about function is in the pool at index. Construct the
+///  function from this information and bind the current scope.
+       case SWF::ABC_ACTION_NEWFUNCTION:
+       {
+               mStack.grow(1);
+               asMethod *m = pool_method(mStream->read_V32());
+               mStack.top(0) = m->construct(mCurrentScope);
+               break;
+       }
+/// 0x41 ABC_ACTION_CALL
+/// Stream: V32 'arg_count'
+/// Stack In:
+///  argN ... arg1 -- the arg_count arguments to pass
+///  obj -- the object to which the function belongs
+///  func -- the function to be called
+/// Stack Out:
+///  value -- the value returned by obj->func(arg1, ...., argN)
+       case SWF::ABC_ACTION_CALL:
+       {
+               uint32_t argc = mStream->read_V32();
+               ENSURE_OBJECT(mStack.top(argc + 1));
+               as_function *f = mStack.top(argc + 1).to_as_function();
+               // argc + 1 will be dropped, and mStack.top(argc + 1)
+               // will be the top of the stack, so that is where the
+               // return value should go. (Currently it is the func)
+               asBinding b(f);
+               pushCall(argc + 1, &mStack.top(argc + 1), &b);
+               break;
+       }
+/// 0x42 ABC_ACTION_CONSTRUCT
+/// Stream: V32 'arg_count'
+/// Stack In:
+///  argN ... arg1 -- the arg_count arguments to pass
+///  function -- constructor for the object to be constructed
+/// Stack Out:
+///  value -- obj after it has been constructed as obj(arg1, ..., argN)
+       case SWF::ABC_ACTION_CONSTRUCT:
+       {
+               uint32_t argc = mStream->read_V32();
+               as_function *f = mStack.top(argc).to_as_function();
+               asBinding b(f);
+               pushCall(argc, &mStack.top(argc), &b);
+               break;
+       }
+/// 0x43 ABC_ACTION_CALLMETHOD
+/// Stream: V32 'method_id + 1' | V32 'arg_count'
+/// Stack In:
+///  argN ... arg1 -- the arg_count arguments to pass
+///  obj -- the object to be called
+/// Stack Out:
+///  value -- the value returned by obj::'method_id'(arg1, ..., argN)
+       case SWF::ABC_ACTION_CALLMETHOD:
+       {
+               uint32_t dispatch_id = mStream->read_V32() - 1;
+               uint32_t argc = mStream->read_V32();
+               ENSURE_OBJECT(mStack.top(argc));
+               as_object *obj = mStack.top(argc).to_object().get();
+               asBinding *b = obj->bindingAtIndex(dispatch_id);
+               if (!b)
+               {
+                       mStack.drop(argc);
+                       mStack.top(0).set_undefined();
+                       break;
+               }
+               pushCall(argc + 1, &mStack.top(argc), b);
+               break;
+       }
+/// 0x44 ABC_ACTION_CALLSTATIC
+/// Stream: V32 'method_id' | V32 'arg_count'
+/// Stack In:
+///  argN ... arg1 -- the arg_count arguments to pass
+///  obj -- the object to act as a receiver for the static call
+/// Stack Out:
+///  value -- the value returned by obj->ABC::'method_id'(arg1, ..., argN)
+       case SWF::ABC_ACTION_CALLSTATIC:
+       {
+               asMethod *m = pool_method(mStream->read_V32());
+               uint32_t argc = mStream->read_V32();
+               asBinding b(m);
+               pushCall(argc + 1, &mStack.top(argc), &b);
+               break;
+       }
+/// 0x45 ABC_ACTION_CALLSUPER
+/// 0x4E ABC_ACTION_CALLSUPERVOID
+/// Stream: V32 'name_offset' | V32 'arg_count'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff
+///  argN ... arg1 -- the arg_count arguments to pass
+///  obj -- the object whose super is to be called
+/// Stack Out:
+///  0x45: value -- the value returned by 
obj::(resolve)'name_offset'::super(arg1,
+///   ..., argN)
+///  0x4E: .
+       case SWF::ABC_ACTION_CALLSUPER:
+       case SWF::ABC_ACTION_CALLSUPERVOID:
+       {
+               asName a = mStream->read_V32();
+               uint32_t argc = mStream->read_V32();
+               int dropsize = completeName(a);
+               ENSURE_OBJECT(mStack.top(argc + dropsize));
+               mStack.drop(dropsize);
+               asBinding *b = findSuper(mStack.top(argc), 
+                       true)->getBinding(mStack.top(argc), a);
+               if (opcode == SWF::ABC_ACTION_CALLSUPER)
+                       pushCall(argc + 1, &mStack.top(argc), b);
+               else
+                       pushCall(argc + 1, &mIgnoreReturn, b);
+               break;
+       }
+/// 0x46 ABC_ACTION_CALLPROPERTY
+/// 0x4C ABC_ACTION_CALLPROPLEX
+/// 0x4F ABC_ACTION_CALLPROPVOID
+/// Stream: V32 'name_offset' | V32 'arg_count'
+/// Stack In:
+///  argN ... arg1 -- the arg_count arguments to pass
+///  [ns [n]] -- Namespace stuff
+///  obj -- The object whose property is to be accessed.
+/// Stack Out:
+///  value -- the value from obj::(resolve)'name_offset'(arg1, ..., argN)
+///  (unless ABC_ACTION_CALL_PROPVOID, then: . )
+/// NB: Calls getter/setter if they exist.
+/// If the opcode is ABC_ACTION_CALLPROPLEX, obj is not altered by 
getter/setters
+       case SWF::ABC_ACTION_CALLPROPERTY:
+       case SWF::ABC_ACTION_CALLPROPLEX:
+       case SWF::ABC_ACTION_CALLPROPVOID:
+       {
+               bool lex_only = (opcode == SWF::ABC_ACTION_CALLPROPLEX);
+               asName a = mStream->read_V32();
+               uint32_t argc = mStream->read_V32();
+               int shift = completeName(a, argc);
+               ENSURE_OBJECT(mStack.top(shift + argc));
+               // Ugly setup. Any name stuff is between the args and the 
object.
+               if (shift)
+               {
+                       uint32_t i = argc;
+                       while (i--)
+                               mStack.top(i + shift) = mStack.top(i);
+                       mStack.drop(shift);
+               }
+               asBinding *b = mStack.top(argc).to_object()->getBinding(a);
+               b->setLexOnly(lex_only);
+               if (opcode == SWF::ABC_ACTION_CALLPROPVOID)
+                       pushCall(argc + 1, &mIgnoreReturn, b);
+               else
+               pushCall(argc + 1, &mStack.top(argc), b);
+               break;
+       }
+/// 0x47 ABC_ACTION_RETURNVOID
+/// Do: Return an undefined object up the callstack.
+       case SWF::ABC_ACTION_RETURNVOID:
+       {
+               // Slot the return.
+               *mGlobalReturn = as_value();
+               // And restore the previous state.
+               restoreState();
+               break;
+       }
+/// 0x48 ABC_ACTION_RETURNVALUE
+/// Stack In:
+///  value -- value to be returned
+/// Stack Out:
+///  .
+/// Do: Return value up the callstack.
+       case SWF::ABC_ACTION_RETURNVALUE:
+       {
+               // Slot the return.
+               *mGlobalReturn = mStack.top(0);
+               // And restore the previous state.
+               restoreState();
+               break;
+       }
+/// 0x49 ABC_ACTION_CONSTRUCTSUPER
+/// Stream: V32 'arg_count'
+/// Stack In:
+///  obj -- the object whose super's constructor should be invoked
+///  arg1 ... argN -- the arg_count arguments
+/// Stack Out:
+///  .
+       case SWF::ABC_ACTION_CONSTRUCTSUPER:
+       {
+               uint32_t argc = mStream->read_V32();
+               ENSURE_OBJECT(mStack.top(argc));
+               asMethod *m = findSuper(mStack.top(argc), 
true)->getConstructor();
+               asBinding b(m);
+               pushCall(argc + 1, &mIgnoreReturn, &b);
+               break;
+       }
+/// 0x4A ABC_ACTION_CONSTRUCTPROP
+/// Stream: V32 'name_offset' | V32 'arg_count'
+/// Stack In:
+///  argN ... arg1 -- the arg_count arguments to pass
+///  [ns [n]] -- Namespace stuff
+///  obj -- the object whose property should be constructed
+/// Stack Out:
+///  value -- the newly constructed prop from obj::(resolve)
+///   'name_offset'(arg1, ..., argN)
+       case SWF::ABC_ACTION_CONSTRUCTPROP:
+       {
+               asName a = mStream->read_V32();
+               uint32_t argc = mStream->read_V32();
+               int shift = completeName(a, argc);
+               ENSURE_OBJECT(mStack.top(argc + shift));
+               // We have to move the stack if there was a shift.
+               if (shift)
+               {
+                       uint32_t i = argc;
+                       while (i--)
+                               mStack.top(i + shift) = mStack.top(i);
+                       mStack.drop(shift);
+               }
+               // TODO: Finish this (See ECMA spec)
+               break;
+       }
+/// 0x55 ABC_ACTION_NEWOBJECT
+/// Stream: V32 'arg_count'
+/// Stack In:
+///  prop_value_1 -- a value object
+///  prop_name_1 -- a string
+///  .
+///  . (arg_count value/name pairs in all)
+///  .
+///  prop_value_n -- a value object
+///  prop_name_n -- a string
+/// Stack Out:
+///  obj -- A new object which contains all of the given properties.
+/// NB: This builds an object from its properties, it's not a constructor.
+       case SWF::ABC_ACTION_NEWOBJECT:
+       {
+               as_object *obj = mCH->newOfType(NSV::CLASS_OBJECT);
+               uint32_t argc = mStream->read_V32();
+               int i = argc;
+               while (i--)
+               {
+                       obj->set_member(mST.find(mStack.top(i * 2 + 
1).to_string()),
+                               mStack.top(i * 2));
+               }
+               mStack.drop(argc * 2 - 1);
+               mStack.top(0) = obj;
+               break;
+       }
+/// 0x56 ABC_ACTION_NEWARRAY
+/// Stream: V32 'array_size'
+/// Stack In:
+///  value_n -- a value
+///  .
+///  . (array_size of these)
+///  .
+///  value_1 -- a value
+/// Stack Out:
+///  array -- an array { value_1, value_2, ..., value_n }
+       case SWF::ABC_ACTION_NEWARRAY:
+       {
+               uint32_t asize = mStream->read_V32();
+               as_object *obj = mCH->newOfType(NSV::CLASS_ARRAY);
+               as_array_object *array = dynamic_cast<as_array_object*> (obj);
+               array->resize(asize);
+               uint32_t i = asize;
+               while (i--)
+                       array->set_indexed(i, mStack.value(i));
+               mStack.drop(asize - 1);
+               mStack.top(0) = array;
+               break;
+       }
+/// 0x57 ABC_ACTION_NEWACTIVATION
+/// Stack Out:
+///  vtable -- A new virtual table, which has the previous one as a parent.
+       case SWF::ABC_ACTION_NEWACTIVATION:
+       {
+               // TODO
+               break;
+       }
+/// 0x58 ABC_ACTION_NEWCLASS
+/// Stream: V32 'class_id'
+/// Stack In:
+///  obj -- An object to be turned into a class. Its super is constructed.
+/// Stack Out:
+///  class -- The newly made class, made from obj and the information at
+///   cinits_pool[class_id]
+/// NB: This depends on scope and scope base (to determine lifetime(?))
+       case SWF::ABC_ACTION_NEWCLASS:
+       {
+               uint32_t cid = mStream->read_V32();
+               asClass *c = pool_class(cid);
+               asMethod *m = c->getConstructor();
+               asBinding b(m);
+               pushCall(1, &mStack.top(0), &b);
+               break;
+       }
+/// 0x59 ABC_ACTION_GETDESCENDANTS
+/// Stream: V32 'name_id'
+/// Stack In:
+///  value -- Whose descendants to get
+///  [ns [n]] -- Namespace stuff
+/// Stack Out:
+///  ?
+/// NB: This op seems to always throw a TypeError in Tamarin, though I
+/// assume that it ought to do something to yield a list of
+/// descendants of a class.
+       case SWF::ABC_ACTION_GETDESCENDANTS:
+       {
+               asName a = mStream->read_V32();
+               as_value &v = mStack.top(0);
+               ENSURE_OBJECT(v);
+               mStack.drop(1);
+               mStack.drop(completeName(a));
+               // TODO: Decide or discover what to do with this.
+               break;
+       }
+/// 0x5A ABC_ACTION_NEWCATCH
+/// Stream: V32 'catch_id'
+/// Stack Out:
+///  vtable -- vtable suitable to catch an exception of type in catch_id.
+/// NB: Need more information on how exceptions are set up.
+       case SWF::ABC_ACTION_NEWCATCH:
+       {
+               // TODO: Decide if we need this. (Might be a no-op.)
+               break;
+       }
+/// 0x5D ABC_ACTION_FINDPROPSTRICT
+/// 0x5E ABC_ACTION_FINDPROPERTY
+/// Stream: V32 'name_id'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff
+/// Stack Out:
+///  owner -- object which owns property given by looking up the name_id.
+///  0x5D is the undefined object if not found
+///  0x5E throws a ReferenceError if not found
+       case SWF::ABC_ACTION_FINDPROPSTRICT:
+       case SWF::ABC_ACTION_FINDPROPERTY:
+       {
+               asName a = mStream->read_V32();
+               mStack.drop(completeName(a));
+               asBinding *b = findProperty(a);
+               if (!b)
+                       if (opcode == SWF::ABC_ACTION_FINDPROPSTRICT)
+                               throw ASReferenceError();
+                       else
+                               mStack.push(as_value());
+               else
+               {
+                       mStack.push(as_value());
+                       pushCall(0, &mStack.top(0), b);
+               }
+               break;
+       }
+/// 0x5F ABC_ACTION_FINDDEF
+/// Stream: V32 'name_id' (no ns expansion)
+/// Stack Out:
+///  def -- The definition of the name at name_id.
+       case SWF::ABC_ACTION_FINDDEF:
+       {
+               asName a = mStream->read_V32();
+               a.makeComplete();
+               // TODO
+               break;
+       }
+/// 0x60 ABC_ACTION_GETLEX
+/// Stream: V32 'name_id' (no ns expansion)
+/// Stack Out:
+///  property -- The result of 0x5D (ABC_ACTION_FINDPROPSTRICT)
+///   + 0x66 (ABC_ACTION_GETPROPERTY)
+       case SWF::ABC_ACTION_GETLEX:
+       {
+               asName a = mStream->read_V32();
+               a.makeComplete();
+               asBinding *b = findProperty(a);
+               if (!b)
+                       throw ASReferenceError();
+               b->setLexOnly(b);
+               mStack.grow(1);
+               pushCall(0, &mStack.top(0), b);
+               break;
+       }
+/// 0x61 ABC_ACTION_SETPROPERTY
+/// Stream: V32 'name_id'
+/// Stack In:
+///  value -- The value to be used
+///  [ns [n]] -- Namespace stuff
+///      OR
+///  [key] -- Key name for property. Will not have both Namespace and key.
+///  obj -- The object whose property is to be set
+/// Stack Out:
+///  .
+/// NB: If the name at name_id is completely qualified, neither a namespace
+/// nor a key is needed.  If the name_id refers to a name with a runtime
+/// namespace, then this will be used.  If neither of those is true and
+/// obj is a dictionary and key is a name, then the name_id is discarded and
+/// key/value is set in the dictionary obj instead.
+       case SWF::ABC_ACTION_SETPROPERTY:
+       {
+               asName a = mStream->read_V32();
+               //as_value &v = mStack.pop();
+               if (!a.isRuntime())
+               {
+                       //TODO: Set the property of mStack.top(0) v,a
+               }
+               else
+               {
+                       if (a.isRtns() || !(mStack.top(0).is_object()
+                               && mStack.top(1).is_dictionary()))
+                       {
+                               mStack.drop(completeName(a));
+                               //TODO: mStack.top(0).setProperty(a, v);
+                               mStack.drop(1);
+                       }
+                       else
+                       {
+                               //TODO: 
mStack.top(1).setDictProperty(mStack.top(0), v);
+                               mStack.drop(2);
+                       }
+               }
+               break;
+       }
+/// 0x62 ABC_ACTION_GETLOCAL
+/// Stream: V32 'frame_index'
+/// Frame: value at frame_index is needed
+/// Stack Out:
+///  value
+       case SWF::ABC_ACTION_GETLOCAL:
+       {
+               mStack.grow(1);
+               mStack.top(0) = mFrame.value(mStream->read_V32());
+               break;
+       }
+/// 0x63 ABC_ACTION_SETLOCAL
+/// Stream: V32 'frame_index'
+/// Frame: obj at frame_index is set to value
+/// Stack In:
+///  value
+/// Stack Out:
+///  .
+       case SWF::ABC_ACTION_SETLOCAL:
+       {
+               mFrame.value(mStream->read_V32()) = mStack.top(0);
+               mStack.drop(1);
+               break;
+       }
+/// 0x64 ABC_ACTION_GETGLOBALSCOPE
+/// Stack Out:
+///  global -- The global scope object
+       case SWF::ABC_ACTION_GETGLOBALSCOPE:
+       {
+               mStack.grow(1);
+               mStack.top(0) = mGlobalScope;
+               break;
+       }
+/// 0x65 ABC_ACTION_GETSCOPEOBJECT
+/// Stream: S8 'depth'
+/// Stack Out:
+///  scope -- The scope object at depth
+       case SWF::ABC_ACTION_GETSCOPEOBJECT:
+       {
+               uint8_t depth = mStream->read_u8();
+               mStack.grow(1);
+               mStack.top(0) = &mScopeStack.top(depth);
+               break;
+       }
+/// 0x66 ABC_ACTION_GETPROPERTY
+/// Stream: V32 'name_id'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff
+///      OR
+///  [key] -- Key name for property. Will not have both Namespace and key.
+///  obj -- The object whose property is to be retrieved
+/// Stack Out:
+///  prop -- The requested property.
+/// NB: See 0x61 (ABC_ACTION_SETPROPETY) for the decision of ns/key.
+       case SWF::ABC_ACTION_GETPROPERTY:
+       {
+               asName a = mStream->read_V32();
+               if (!a.isRuntime())
+               {
+                       //TODO: mStack.top(0) = mStack.top(0).getProperty(a, v);
+               }
+               else
+               {
+                       if (a.isRtns() || !(mStack.top(0).is_object()
+                               && mStack.top(1).is_dictionary()))
+                       {
+                               mStack.drop(completeName(a));
+                               //TODO: mStack.top(0) = 
mStack.top(0).getProperty(a);
+                       }
+                       else
+                       {
+                               //TODO: mStack.top(1) = 
mStack.top(1).getDictProperty(mStack.top(0));
+                               mStack.drop(1);
+                       }
+               }
+               break;
+       }
+/// 0x68 ABC_ACTION_INITPROPERTY
+/// Stream V32 'name_id'
+/// Stack In:
+///  value -- The value to be put into the property.
+///  [ns [n]] -- Namespace stuff
+///  obj -- The object whose property is to be initialized
+/// Stack Out:
+///  .
+/// Do:
+///  Set obj::(resolve)'name_id' to value, set bindings from the context.
+       case SWF::ABC_ACTION_INITPROPERTY:
+       {
+               asName a = mStream->read_V32();
+               //as_value& v = mStack.pop();
+               mStack.drop(completeName(a));
+               //TODO: mStack.pop().to_object().setProperty(a, v, true); // 
true for init
+               break;
+       }
+/// 0x6A ABC_ACTION_DELETEPROPERTY
+/// Stream: V32 'name_id'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff
+///  obj -- The object whose property should be deleted.
+/// Stack Out:
+///  truth -- True if property was deleted or did not exist, else False.
+       case SWF::ABC_ACTION_DELETEPROPERTY:
+       {
+               asName a = mStream->read_V32();
+               mStack.drop(completeName(a));
+               //mStack.top(0) = mStack.top(0).deleteProperty(a);
+               break;
+       }
+/// 0x6C ABC_ACTION_GETSLOT
+/// Stream: V32 'slot_index + 1'
+/// Stack In:
+///  obj -- The object which owns the desired slot.
+/// Stack Out:
+///  slot -- obj.slots[slot_index]
+       case SWF::ABC_ACTION_GETSLOT:
+       {
+               uint32_t sindex = mStream->read_V32();
+               if (!sindex)
+                       throw ASException();
+               --sindex;
+               //TODO: mStack.top(0) = mStack.top(0).getSlot(sindex);
+               break;
+       }
+/// 0x6D ABC_ACTION_SETSLOT
+/// Stream: V32 'slot_index + 1'
+/// Stack In:
+///  value -- The value intended for the slot.
+///  obj -- The object whose slot should be set.
+/// Stack Out:
+///  .
+/// Do: obj.slots[slot_index] = value
+       case SWF::ABC_ACTION_SETSLOT:
+       {
+               uint32_t sindex = mStream->read_V32();
+               if (!sindex)
+                       throw ASException();
+               --sindex;
+               //TODO: mStack.top(0).setSlot(sindex, mStack.top(1));
+               mStack.drop(2);
+               break;
+       }
+/// 0x6E ABC_ACTION_GETGLOBALSLOT
+/// Stream: V32 'slot_index + 1'
+/// Stack In:
+///  .
+/// Stack Out:
+///  slot -- globals.slots[slot_index]
+/// NB: Deprecated
+       case SWF::ABC_ACTION_GETGLOBALSLOT:
+       {
+               uint32_t sindex = mStream->read_V32();
+               if (!sindex)
+                       throw ASException();
+               --sindex;
+               mStack.grow(1);
+               //TODO: mStack.top(0) = mGlobal.getSlot(sindex);
+               break;
+       }
+/// 0x6F ABC_ACTION_SETGLOBALSLOT
+/// Stream: V32 'slot_index + 1'
+/// Stack In:
+///  value -- The value to be placed into the slot.
+/// Stack Out:
+///  .
+/// Do: globals[slot_index] = value
+/// NB: Deprecated
+       case SWF::ABC_ACTION_SETGLOBALSLOT:
+       {
+               uint32_t sindex = mStream->read_V32();
+               if (!sindex)
+                       throw ASException();
+               --sindex;
+               //TODO: mGlobal.setSlot(sindex, mStack.pop());
+               break;
+       }
+/// 0x70 ABC_ACTION_CONVERT_S
+/// Stack In:
+///  value -- An object
+/// Stack Out:
+///  str_value -- value as a string
+       case SWF::ABC_ACTION_CONVERT_S:
+       {
+               mStack.top(0) = mStack.top(0).to_string();
+               break;
+       }
+/// 0x71 ABC_ACTION_ESC_XELEM
+/// Stack In:
+///  value -- An object to be escaped
+/// Stack Out:
+///  str_value -- value as a string, escaped suitably for an XML element.
+       case SWF::ABC_ACTION_ESC_XELEM:
+       {
+               //TODO: mStack.top(0) = mStack.top(0).to_escaped_xml_element();
+               break;
+       }
+/// 0x72 ABC_ACTION_ESC_XATTR
+/// Stack In:
+///  value -- An object to be escaped
+/// Stack Out:
+///  str_value -- value as a string, escaped suitably for an XML attribute.
+       case SWF::ABC_ACTION_ESC_XATTR:
+       {
+               //TODO: mStack.top(0) = 
mStack.top(0).to_escaped_xml_attribute();
+               break;
+       }
+/// 0x73 ABC_ACTION_CONVERT_I
+/// 0x83 ABC_ACTION_COERCE_I (deprecated)
+/// Stack In:
+///  value -- An object to be converted to Integer
+/// Stack Out:
+///  int_value -- value as an integer object
+       case SWF::ABC_ACTION_CONVERT_I:
+       case SWF::ABC_ACTION_COERCE_I:
+       {
+               mStack.top(0) = mStack.top(0).to_number<int>();
+               break;
+       }
+/// 0x74 ABC_ACTION_CONVERT_U
+/// 0x88 ABC_ACTION_COERCE_U (deprecated)
+/// Stack In:
+///  value -- An object to be converted to unsigned integer
+/// Stack Out:
+///  int_value -- value as an unsigned integer object
+       case SWF::ABC_ACTION_CONVERT_U:
+       case SWF::ABC_ACTION_COERCE_U:
+       {
+               mStack.top(0) = mStack.top(0).to_number<unsigned int>();
+               break;
+       }
+/// 0x75 ABC_ACTION_CONVERT_D
+/// 0x84 ABC_ACTION_COERCE_D (deprecated)
+/// Stack In:
+///  value -- An object to be converted to a double
+/// Stack Out:
+///  double_value -- value as a double object
+       case SWF::ABC_ACTION_CONVERT_D:
+       case SWF::ABC_ACTION_COERCE_D:
+       {
+               mStack.top(0) = mStack.top(0).to_number();
+               break;
+       }
+/// 0x76 ABC_ACTION_CONVERT_B
+/// 0x81 ABC_ACTION_COERCE_B (deprecated)
+/// Stack In:
+///  value -- An object to be converted to a boolean
+/// Stack Out:
+///  bool_value -- value as a boolean object
+       case SWF::ABC_ACTION_CONVERT_B:
+       case SWF::ABC_ACTION_COERCE_B:
+       {
+               mStack.top(0).set_bool(mStack.top(0).to_bool());
+               break;
+       }
+/// 0x77 ABC_ACTION_CONVERT_O
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  obj -- An object
+/// Do: If obj is Undefined or Null, throw TypeError
+       case SWF::ABC_ACTION_CONVERT_O:
+       {
+               mStack.top(0) = mStack.top(0).to_object().get();
+               if (mStack.top(0).is_undefined() || mStack.top(0).is_null())
+                       throw ASTypeError();
+               break;
+       }
+/// 0x78 ABC_ACTION_CHECKFILTER
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  obj -- An object
+/// Do: If obj is not XML based, throw TypeError
+       case SWF::ABC_ACTION_CHECKFILTER:
+       {
+               if (!mStack.top(0).is_xml())
+                       throw ASTypeError();
+               break;
+       }
+/// 0x80 ABC_ACTION_COERCE
+/// Stream: V32 'name_index'
+/// Stack In:
+///  [ns [n]] -- Possibly name/namespace stuff
+///  obj -- An object to be converted
+/// Stack Out:
+///  coerced_obj -- The object as the desired (resolve)'name_index' type.
+       case SWF::ABC_ACTION_COERCE:
+       {
+               asName a = mStream->read_V32();
+               mStack.drop(completeName(a));
+               //TODO: mStack.top(0) = mStack.top(0).coerce(a);
+               break;
+       }
+/// 0x82 ABC_ACTION_COERCE_A
+/// Stack In:
+///  obj -- An object to be converted
+/// Stack Out:
+///  obj
+/// Do: Nothing. (The 'a' is for atom, and it's unclear if anything is needed.)
+       case SWF::ABC_ACTION_COERCE_A:
+       {
+               break;
+       }
+/// 0x85 ABC_ACTION_COERCE_S
+/// Stack In:
+///  obj -- An object to be converted
+/// Stack Out:
+///  str_obj -- obj as string. nullString object if obj is Null or Undefined
+       case SWF::ABC_ACTION_COERCE_S:
+       {
+               if (mStack.top(0).is_undefined() || mStack.top(0).is_null())
+                       mStack.top(0) = "";
+               else
+                       mStack.top(0) = mStack.top(0).to_string();
+               break;
+       }
+/// 0x86 ABC_ACTION_ASTYPE
+/// Stream: V32 'name_index'
+/// Stack In:
+///  [ns [n]] -- Possible namespace stuff
+///  obj -- An object to be checked
+/// Stack Out:
+///  cobj -- obj if obj is of type (resolve)'name_index', otherwise Null
+       case SWF::ABC_ACTION_ASTYPE:
+       {
+               asName a = mStream->read_V32();
+               mStack.drop(completeName(a));
+               if (!mStack.top(0).conforms_to(a))
+                       mStack.top(0).set_null();
+               break;
+       }
+/// 0x87 ABC_ACTION_ASTYPELATE
+/// Stack In:
+///  valid -- The object whose type is to be matched
+///  obj -- An object to be checked
+/// Stack Out:
+///  cobj -- obj if type of obj conforms to valid, otherwise Null
+       case SWF::ABC_ACTION_ASTYPELATE:
+       {
+               if (!mStack.top(1).conforms_to(mStack.top(0)))
+                       mStack.top(1).set_null();
+               mStack.drop(1);
+               break;
+       }
+/// 0x89 ABC_ACTION_COERCE_O
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  cobj -- obj if obj is not Undefined, otherwise Null
+       case SWF::ABC_ACTION_COERCE_O:
+       {
+               if (mStack.top(0).is_undefined())
+                       mStack.top(0) = mStack.top(0).to_object().get();
+               else
+                       mStack.top(0).set_undefined();
+               break;
+       }
+/// 0x90 ABC_ACTION_NEGATE
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  negdouble -- -1.0 * (double) obj
+       case SWF::ABC_ACTION_NEGATE:
+       {
+               mStack.top(0) = -mStack.top(0).to_number();
+               break;
+       }
+/// 0x91 ABC_ACTION_INCREMENT
+/// Stack In:
+///  num -- A number, integer or double
+/// Stack Out:
+///  num + 1
+       case SWF::ABC_ACTION_INCREMENT:
+       {
+               mStack.top(0) = mStack.top(0).to_number() + 1;
+               break;
+       }
+/// 0x92 ABC_ACTION_INCLOCAL
+/// Stream: V32 'frame_addr'
+/// Frame: Load i from frame_addr and increment it.
+       case SWF::ABC_ACTION_INCLOCAL:
+       {
+               uint32_t foff = mStream->read_V32();
+               mFrame.value(foff) = mFrame.value(foff).to_number() + 1;
+               break;
+       }
+/// 0x93 ABC_ACTION_DECREMENT
+/// Stack In:
+///  num -- A number, integer or double
+/// Stack Out:
+///  num - 1
+       case SWF::ABC_ACTION_DECREMENT:
+       {
+               mStack.top(0) = mStack.top(0).to_number() - 1;
+               break;
+       }
+/// 0x94 ABC_ACTION_DECLOCAL
+/// Stream: V32 'frame_addr'
+/// Frame: Load i from frame_addr and decrement it.
+       case SWF::ABC_ACTION_DECLOCAL:
+       {
+               uint32_t foff = mStream->read_V32();
+               mFrame.value(foff) = mFrame.value(foff).to_number() - 1;
+               break;
+       }
+/// 0x95 ABC_ACTION_ABC_TYPEOF
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  type -- typeof(obj) as a string
+       case SWF::ABC_ACTION_ABC_TYPEOF:
+       {
+               mStack.top(0) = mStack.top(0).typeOf();
+               break;
+       }
+/// 0x96 ABC_ACTION_NOT
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  nobj -- A truth object with value !((Boolean) obj)
+       case SWF::ABC_ACTION_NOT:
+       {
+               mStack.top(0).set_bool(!mStack.top(0).to_bool());
+               break;
+       }
+/// 0x97 ABC_ACTION_BITNOT
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  nint -- ~((Int) obj)
+       case SWF::ABC_ACTION_BITNOT:
+       {
+               mStack.top(0) = ~mStack.top(0).to_number<int>();
+               break;
+       }
+/// 0xA0 ABC_ACTION_ADD        
+/// Stack In:
+/// a
+/// b
+/// Stack Out:
+/// a + b (double if numeric)
+       case SWF::ABC_ACTION_ADD:
+       {
+               //TODO: mStack.top(1) = mStack.top(1).add(mStack.top(0));
+               mStack.drop(1);
+               break;
+       }
+/// 0xA1 ABC_ACTION_SUBTRACT
+/// Stack In:
+///  a
+///  b
+/// Stack Out:
+///  a - b (double)
+       case SWF::ABC_ACTION_SUBTRACT:
+       {
+               mStack.top(1) = mStack.top(1).to_number() - 
mStack.top(1).to_number();
+               mStack.drop(1);
+               break;
+       }
+/// 0xA2 ABC_ACTION_MULTIPLY
+/// Stack In:
+///  a
+///  b
+/// Stack Out:
+///  a * b (double)
+       case SWF::ABC_ACTION_MULTIPLY:
+       {
+               mStack.top(1) = mStack.top(1).to_number() * 
mStack.top(0).to_number();
+               mStack.drop(1);
+               break;
+       }
+/// 0xA3 ABC_ACTION_DIVIDE
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a / b (double)
+       case SWF::ABC_ACTION_DIVIDE:
+       {
+               mStack.top(1) = mStack.top(1).to_number() / 
mStack.top(0).to_number();
+               mStack.drop(1);
+               break;
+       }
+/// 0xA4 ABC_ACTION_MODULO
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a % b (not integer mod, but remainder)
+       case SWF::ABC_ACTION_MODULO:
+       {
+               double result = mStack.top(1).to_number() / 
mStack.top(0).to_number();
+               int trunc_result = static_cast<int> (result);
+               mStack.top(1) = mStack.top(1).to_number<double>() - 
+                       (trunc_result * mStack.top(0).to_number<double>());
+               mStack.drop(1);
+               break;
+       }
+/// 0xA5 ABC_ACTION_LSHIFT
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a << b
+       case SWF::ABC_ACTION_LSHIFT:
+       {
+               mStack.top(1) = mStack.top(1).to_number<int>() << 
mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xA6 ABC_ACTION_RSHIFT
+/// Stack In:
+///  a
+///  b
+/// Stack Out:
+///  a >> b
+       case SWF::ABC_ACTION_RSHIFT:
+       {
+               mStack.top(1) = mStack.top(1).to_number<int>() >> 
mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xA7 ABC_ACTION_URSHIFT
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  ((unsigned) a) >> b
+       case SWF::ABC_ACTION_URSHIFT:
+       {
+               mStack.top(1) = mStack.top(1).to_number<unsigned int>()
+                       >> mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xA8 ABC_ACTION_BITAND
+///  a
+///  b
+/// Stack Out:
+///  a & b
+       case SWF::ABC_ACTION_BITAND:
+       {
+               mStack.top(1) = mStack.top(1).to_number<int>() & 
mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xA9 ABC_ACTION_BITOR
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a | b
+       case SWF::ABC_ACTION_BITOR:
+       {
+               mStack.top(1) = mStack.top(1).to_number<int>() | 
mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xAA ABC_ACTION_BITXOR
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a ^ b
+       case SWF::ABC_ACTION_BITXOR:
+       {
+               mStack.top(1) = mStack.top(1).to_number<int>() ^ 
mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xAB ABC_ACTION_EQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a == b) (weakly)
+       case SWF::ABC_ACTION_EQUALS:
+       {
+               bool truth;
+               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), false);
+               mStack.drop(1);
+               mStack.top(0).set_bool(truth);
+               break;
+       }
+/// 0xAC ABC_ACTION_STRICTEQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a == b) (strongly, as in 
+///   0x19 (ABC_ACTION_IFSTRICTEQ))
+       case SWF::ABC_ACTION_STRICTEQUALS:
+       {
+               bool truth;
+               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), true);
+               mStack.drop(1);
+               mStack.top(0).set_bool(truth);
+               break;
+       }
+/// 0xAD ABC_ACTION_LESSTHAN
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a < b)
+       case SWF::ABC_ACTION_LESSTHAN:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), false);
+               mStack.drop(1);
+               mStack.top(0).set_bool(truth); // truth is a < b
+               break;
+       }
+/// 0xAE ABC_ACTION_LESSEQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a <= b)
+       case SWF::ABC_ACTION_LESSEQUALS:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), true);
+               mStack.drop(1);
+               mStack.top(0).set_bool(!truth); // truth is b < a
+               break;
+       }
+/// 0xAF ABC_ACTION_GREATERTHAN
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a > b)
+       case SWF::ABC_ACTION_GREATERTHAN:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), false);
+               mStack.drop(1);
+               mStack.top(0).set_bool(truth); // truth is b < a
+               break;
+       }
+/// 0xB0 ABC_ACTION_GREATEREQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a >= b)
+       case SWF::ABC_ACTION_GREATEREQUALS:
+       {
+               bool truth;
+               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), true);
+               mStack.drop(1);
+               mStack.top(0).set_bool(!truth); // truth is a < b
+               break;
+       }
+/// 0xB1 ABC_ACTION_INSTANCEOF
+/// Stack In:
+///  super -- An object
+///  val -- An object
+/// Stack Out:
+///  truth -- Truth of "val is an instance of super"
+       case SWF::ABC_ACTION_INSTANCEOF:
+       {
+               if (mStack.top(1).is_null())
+                       mStack.top(1) = false;
+               else // Calling to_object intentionally causes an exception if 
super is not an object.
+                       mStack.top(1) = 
mStack.top(1).conforms_to(mStack.top(0));
+               mStack.drop(1);
+               break;
+       }
+/// 0xB2 ABC_ACTION_ISTYPE
+/// Stream: V32 'name_id'
+/// Stack In:
+///  [ns] -- Namespace stuff
+///  obj -- An object
+/// Stack Out:
+///  truth -- Truth of "obj is of the type given in (resolve)'name_id'"
+       case SWF::ABC_ACTION_ISTYPE:
+       {
+               asName a = mStream->read_V32();
+               mStack.drop(completeName(a));
+               mStack.top(0).set_bool(mStack.top(0).conforms_to(a));
+       }
+/// 0xB3 ABC_ACTION_ISTYPELATE
+/// Stack In:
+///  type -- A type to match
+///  obj -- An object
+/// Stack Out:
+///  truth -- Truth of "obj is of type"
+       case SWF::ABC_ACTION_ISTYPELATE:
+       {
+               
mStack.top(1).set_bool(mStack.top(1).conforms_to(mStack.top(0)));
+               mStack.drop(1);
+               break;
+       }
+/// 0xB4 ABC_ACTION_IN
+/// Stack In:
+///  obj -- The object to search for it
+///  name -- The name to find
+/// Stack Out:
+///  truth -- True if name is in current namespace or anywhere in object.
+///   Don't look in the namespace if obj is a dictionary.
+/// NB: Since there doesn't seem to be a way to make a dictionary, this
+/// is not done. If there is, fix this lack.
+       case SWF::ABC_ACTION_IN:
+       {
+               //TODO: 
mStack.top(1).set_bool(mStack.top(1).to_object().contains(mStack.top(0)));
+               mStack.drop(1);
+               break;
+       }
+/// 0xC0 ABC_ACTION_INCREMENT_I
+/// See: 0x91 (ABC_ACTION_INCREMENT), but forces types to int, not double
+       case SWF::ABC_ACTION_INCREMENT_I:
+       {
+               mStack.top(0) = mStack.top(0).to_number<int>() + 1;
+               break;
+       }
+/// 0xC1 ABC_ACTION_DECREMENT_I
+/// See: 0x93 (ABC_ACTION_DECREMENT), but forces types to int, not double
+       case SWF::ABC_ACTION_DECREMENT_I:
+       {
+               mStack.top(0) = mStack.top(0).to_number<int>() - 1;
+               break;
+       }
+/// 0xC2 ABC_ACTION_INCLOCAL_I
+/// See: 0x92 (ABC_ACTION_INCLOCAL), but forces types to int, not double
+       case SWF::ABC_ACTION_INCLOCAL_I:
+       {
+               uint32_t foff = mStream->read_V32();
+               mFrame.value(foff) = mFrame.value(foff).to_number<int>() + 1;
+               break;
+       }
+/// 0xC3 ABC_ACTION_DECLOCAL_I
+/// See: 0x94 (ABC_ACTION_DECLOCAL), but forces types to int, not double
+       case SWF::ABC_ACTION_DECLOCAL_I:
+       {
+               uint32_t foff = mStream->read_V32();
+               mFrame.value(foff) = mFrame.value(foff).to_number<int>() - 1;
+               break;
+       }
+/// 0xC4 ABC_ACTION_NEGATE_I
+/// See: 0x90 (ABC_ACTION_NEGATE), but forces type to int, not double
+       case SWF::ABC_ACTION_NEGATE_I:
+       {
+               mStack.top(0) = - mStack.top(0).to_number<int>();
+               break;
+       }
+/// 0xC5 ABC_ACTION_ADD_I
+/// See: 0xA0 (ABC_ACTION_ADD), but forces type to int
+       case SWF::ABC_ACTION_ADD_I:
+       {
+               mStack.top(1) = mStack.top(1).to_number<int>() + 
mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xC6 ABC_ACTION_SUBTRACT_I
+/// See: 0xA1 (ABC_ACTION_SUBTRACT), but forces type to int
+       case SWF::ABC_ACTION_SUBTRACT_I:
+       {
+               mStack.top(1) = mStack.top(1).to_number<int>() - 
mStack.top(0).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xC7 ABC_ACTION_MULTIPLY_I
+/// See: 0xA2 (ABC_ACTION_MULTIPLY), but forces type to int
+       case SWF::ABC_ACTION_MULTIPLY_I:
+       {
+               mStack.top(1) = mStack.top(0).to_number<int>() * 
mStack.top(1).to_number<int>();
+               mStack.drop(1);
+               break;
+       }
+/// 0xD0 ABC_ACTION_GETLOCAL0
+/// 0xD1 ABC_ACTION_GETLOCAL1
+/// 0xD2 ABC_ACTION_GETLOCAL2
+/// 0xD3 ABC_ACTION_GETLOCAL3
+/// Frame: Load frame[#] as val
+/// Stack Out:
+///  val
+       case SWF::ABC_ACTION_GETLOCAL0:
+       case SWF::ABC_ACTION_GETLOCAL1:
+       case SWF::ABC_ACTION_GETLOCAL2:
+       case SWF::ABC_ACTION_GETLOCAL3:
+       {
+               mStack.grow(1);
+               mStack.top(0) = mFrame.value(opcode - 
SWF::ABC_ACTION_GETLOCAL0);
+               break;
+       }
+/// 0xD4 ABC_ACTION_SETLOCAL0
+/// 0xD5 ABC_ACTION_SETLOCAL1
+/// 0xD6 ABC_ACTION_SETLOCAL2
+/// 0xD7 ABC_ACTION_SETLOCAL3
+/// Frame: Store val as frame[#]
+/// Stack In:
+///  val
+/// Stack Out:
+///  .
+       case SWF::ABC_ACTION_SETLOCAL0:
+       case SWF::ABC_ACTION_SETLOCAL1:
+       case SWF::ABC_ACTION_SETLOCAL2:
+       case SWF::ABC_ACTION_SETLOCAL3:
+       {
+               mFrame.value(opcode - SWF::ABC_ACTION_SETLOCAL0) = 
mStack.top(0);
+               mStack.drop(1);
+               break;
+       }
+
+/// 0xEF ABC_ACTION_DEBUG
+/// Stream: 7 bytes of unknown stuff to be skipped
+/// Do: skip ahead 7 bytes in stream
+       case SWF::ABC_ACTION_DEBUG:
+       {
+               mStream->seekBy(7);
+               break;
+       }
+/// 0xF0 ABC_ACTION_DEBUGLINE
+/// Stream: V32 'line_number'
+/// Do: Nothing, but line_number is for the debugger if wanted.
+       case SWF::ABC_ACTION_DEBUGLINE:
+       {
+               mStream->skip_V32();
+               break;
+       }
+/// 0xF1 ABC_ACTION_DEBUGFILE
+/// Stream: V32 'name_offset'
+/// Do: Nothing. 'name_offset' into string pool is the file name if wanted.
+       case SWF::ABC_ACTION_DEBUGFILE:
+       {
+               mStream->skip_V32();
+               break;
+       }
+/// 0xF2 ABC_ACTION_BKPTLINE
+/// Stream: V32 'line_number'
+/// Do: Enter debugger if present, line_number is the line number in source.
+       case SWF::ABC_ACTION_BKPTLINE:
+       {
+               mStream->skip_V32();
+               break;
+       }
+       } // end of switch statement
+       } // end of AS3 conditional
+       else // beginning of !AS3 (this code is AS2)
+       {
+       switch (opcode)
+       {
+       } // end of switch statement
+       } // end of AS2 conditional (!AS3)
+       } // end of main loop
+} // end of execute function
+
+void
+Machine::getMember(asClass* pDefinition, asName& name,
+       as_value& instance)
+{
+       if (!instance.is_object())
+               throw ASTypeError();
+
+       asBinding *pBinding = pDefinition->getBinding(instance, name);
+       if (pBinding->isWriteOnly())
+               throw ASReferenceError();
+
+       if (!pBinding->isGetSet())
+       {
+               //TODO: mStack.push(pBinding->getFromInstance(instance));
+               return;
+       }
+
+       // This is a getter, so we need to execute it. Even those
+       // written in C++ get called like this, with pushCall handling.
+       // And push the instance ('this')
+       mStack.push(instance);
+       pushCall(1, &mStack.top(0), pBinding); //TODO: pBinding->getGetter());
+}
+
+void
+Machine::setMember(asClass *pDefinition, asName& name, as_value& instance,
+       as_value& newvalue)
+{
+       if (!instance.is_object())
+               throw ASReferenceError();
+
+       asBinding *pBinding = pDefinition->getBinding(instance, name);
+
+       if (pBinding->isReadOnly())
+               throw ASReferenceError();
+
+       if (!pBinding->isGetSet())
+       {
+               //TODO: pBinding->setInInstance(instance, newvalue);
+               return;
+       }
+
+       // Two parameters -- the target object, the value to set.
+       mStack.push(instance);
+       mStack.push(newvalue);
+       pushCall(2, &mStack.top(1), pBinding); //TODO: pBinding->getSetter());
+}
+
+int
+Machine::completeName(asName &name, int offset)
+{
+       int size = 0;
+
+       asName* uname = pool_name(name.id);
+       if (uname->isRuntime())
+       {
+               as_value obj = mStack.top(offset);
+               if (obj.is_object() && obj.to_object()->isQName())
+                       name.fill(obj.to_object().get());
+               ++size;
+
+               if (uname->isRtns())
+                       ++size; // Ignore the Namespace.
+       }
+       else if (uname->isRtns())
+       {
+               uname->setNamespace(mStack.top(offset));
+               ++size;
+       }
+       return size;
+}
+
+asClass *
+Machine::findSuper(as_value &v, bool find_for_primitive)
+{
+       if (v.is_undefined() || v.is_null())
+               return NULL;
+
+       if (v.is_object())
+       {
+               asClass *pProto = NULL; // TODO: v.to_object()->getClass();
+               return pProto ? pProto->getSuper() : NULL;
+       }
+
+       if (!find_for_primitive)
+               return NULL;
+
+       if (v.is_number())
+       {
+               return NULL; // TODO: mCH->getClass(NSV::CLASS_NUMBER);
+       }
+
+       // And so on...
+       // TODO: Other primitives
+       return NULL;
+}
+
+void
+Machine::pushCall(unsigned int stack_in, as_value *return_slot,
+       asBinding *pBind)
+{
+       switch (pBind->mType)
+       {
+       default:
+       case asBinding::T_ACCESS:
+       case asBinding::T_CLASS:
+               throw ASException();
+               return;
+       case asBinding::T_VALUE:
+               *return_slot = pBind->getValue()->getCurrentValue();
+               return;
+       case asBinding::T_METHOD:
+               break;
+       }
+
+       asMethod *m = pBind->getMethod();
+
+       if (!(m->isNative() || m->hasBody()))
+               throw ASException();
+
+       // Here is where the SafeStack shines:
+       // We set the stack the way it should be on return.
+       // If the return slot is the deepest parameter, leave room for it.
+       if (stack_in && (return_slot == &mStack.top(stack_in - 1)))
+               mStack.drop(stack_in - 1);
+       else // The return slot is somewhere else.
+               mStack.drop(stack_in);
+       // We save that state.
+       saveState();
+       // We make the stack appear empty.
+       mStack.fixDownstop();
+       // We grow to reclaim the parameters. Since this is a SafeStack, they
+       // were not lost.
+       mStack.grow(stack_in);
+
+       // Native functions have to be called now.
+       if (m->isNative())
+       {
+               //TODO: return_slot = m->CallNative(mStack, mGlobalScope);
+               restoreState();
+               return;
+       }
+
+       // The scope stack should be fixed for non-native calls.
+       mScopeStack.fixDownstop();
+       //TODO: mScopeStack.push(m->getActivation());
+       mCurrentScope = &mScopeStack.top(0);
+
+       // We set the stream and return as given in the method and call.
+       //TODO: mStream = m->getBody();
+       mGlobalReturn = return_slot;
+
+       // When control goes to the main loop of the interpreter, it will
+       // automatically start executing the method.
+}
+
+void
+Machine::restoreState()
+{
+       State &s = mStateStack.top(0);
+       mStack.setAllSizes(s.mStackTotalSize, s.mStackDepth);
+       mScopeStack.setAllSizes(s.mScopeTotalSize, s.mScopeStackDepth);
+       mStream = s.mStream;
+       mDefaultXMLNamespace = s.mDefaultXMLNamespace;
+       mCurrentScope = s.mCurrentScope;
+       mGlobalReturn = s.mGlobalReturn;
+       mStateStack.drop(1);
+}
+
+void
+Machine::saveState()
+{
+       mStateStack.grow(1);
+       State &s = mStateStack.top(0);
+       s.mStackDepth = mStack.getDownstop();
+       s.mStackTotalSize = mStack.totalSize();
+       s.mScopeStackDepth = mScopeStack.getDownstop();
+       s.mScopeTotalSize = mScopeStack.totalSize();
+       s.mStream = mStream;
+       s.mDefaultXMLNamespace = mDefaultXMLNamespace;
+       s.mCurrentScope = mCurrentScope;
+       s.mGlobalReturn = mGlobalReturn;
+}
+
+} // end of namespace gnash

Index: server/vm/AbcHandlers.cpp
===================================================================
RCS file: server/vm/AbcHandlers.cpp
diff -N server/vm/AbcHandlers.cpp
--- server/vm/AbcHandlers.cpp   8 Oct 2007 06:55:11 -0000       1.5
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,2232 +0,0 @@
-//
-//   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 <boost/logic/tribool.hpp>
-
-#define ENSURE_NUMBER(vte)                                                     
                        \
-{                                                                              
                                                                \
-       as_value &a = vte; /* Don't call vte multiple times */                  
        \
-       if (vte.is_object())                                                    
                                        \
-       {                                                                       
                                                                \
-               asBinding *b = a.to_object()->getBinding(NSV::PROP_VALUE_OF);   
\
-               if (b)                                                          
                                                        \
-               {                                                               
                                                                \
-                       mStream->seekTo(mOpStart);                              
                                        \
-                       mStack.push(vte);                                       
                                                \
-                       pushCall(1, &vte, b);                                   
                                        \
-                       break;                                                  
                                                        \
-               }                                                               
                                                                \
-       }                                                                       
                                                                \
-}                                                                              
           /* end of ENSURE_NUMBER */
-
-#define ENSURE_OBJECT(vte, backup)                                             
                                \
-{                                                                              
                                                                \
-       if (!vte.is_object())                                                   
                                        \
-               throw ASMalformedError();                                       
                                        \
-}                                                                              
           /* end of ENSURE_OBJECT */
-
-#define ENSURE_STRING(vte, backup)                                             
                                \
-{                                                                              
                                                                \
-       as_value &a = vte; /* Don't call vte multiple times */                  
        \
-       if (a.is_object())                                                      
                                                \
-       {                                                                       
                                                                \
-               asBinding *b = a.to_object()->getBinding(NSV::PROP_TO_STRING);  
\
-               if (b)                                                          
                                                        \
-               {                                                               
                                                                \
-                       mStream->seekTo(mOpStart);                              
                                        \
-                       mStack.push(vte);                                       
                                                \
-                       pushCall(1, &vte, b);                                   
                                        \
-                       break;                                                  
                                                        \
-               }                                                               
                                                                \
-       }                                                                       
                                                                \
-}                                                                              
           /* end of ENSURE_STRING */
-
-#define ABSTRACT_COMPARE(store, rv1, rv2, truth_of_undefined)                  
\
-{                                                                              
                                                                \
-       as_value &a = rv1; /* Don't call rv1 multiple times */                  
        \
-       as_value &b = rv2; /* Don't call rv2 multiple times */                  
        \
-       if (a.ptype() == PTYPE_STRING && b.ptype() == PTYPE_STRING)             
\
-       {                                                                       
                                                                \
-               ENSURE_STRING(a);                                               
                                                \
-               ENSURE_STRING(b);                                               
                                                \
-               std::string &str_a = a.to_string();                             
                        \
-               std::string &str_b = b.to_string();                             
                        \
-               store = a < b;                                                  
                                                \
-       }                                                                       
                                                                \
-       else                                                                    
                                                        \
-       {                                                                       
                                                                \
-               ENSURE_NUMBER(a);                                               
                                                \
-               ENSURE_NUMBER(b);                                               
                                                \
-               if (a.is_nan() || b.is_nan())                                   
                                \
-                       store = truth_of_undefined;                             
                                \
-               else if (a.is_positive_infinity())                              
                                \
-                       store = false;                                          
                                                \
-               else if (b.is_positive_infinity())                              
                                \
-                       store = true;                                           
                                                \
-               else if (b.is_negative_infinity())                              
                                \
-                       store = false;                                          
                                                \
-               else if (a.is_negative_infinity())                              
                                \
-                       store = true;                                           
                                                \
-               else                                                            
                                                        \
-                       store = a.to_number() < b.to_number();                  
                        \
-       }                                                                       
                                                                \
-}                                                                              
        /* end of ABSTRACT_COMPARE */
-
-#define ABSTRACT_EQUALITY(store, ev1, ev2, strictness_on)                      
        \
-{                                                                              
                                                                \
-       as_value &a = ev1; /* Don't call ev1 multiple times */                  
        \
-       as_value &b = ev2; /* Don't call ev2 multiple times */                  
        \
-       if (a.is_object() && b.is_object())                                     
                                \
-               store = a.to_object() == b.to_object();                         
                        \
-       else if (a.is_object() || b.is_object())                                
                        \
-               store = false;                                                  
                                                \
-       else if (a.ptype() != b.ptype())                                        
                                \
-       {                                                                       
                                                                \
-               if (!strictness_on && (a.is_undefined() || b.is_undefined()) && 
\
-                       (a.is_null() || b.is_null())                            
                                \
-                       store = true;                                           
                                                \
-               else                                                            
                                                        \
-                       store = false;                                          
                                                \
-       }                                                                       
                                                                \
-       else if (a.is_number())                                                 
                                        \
-       {                                                                       
                                                                \
-               if (a.is_nan() || b.is_nan())                                   
                                \
-                       store = false;                                          
                                                \
-               else if (a.is_positive_infinity() && b.is_positive_infinity())  
\
-                       store = true;                                           
                                                \
-               else if (a.is_negative_infinity() && b.is_negative_infinity())  
\
-                       store = true;                                           
                                                \
-               else                                                            
                                                        \
-                       store = a.to_number() == b.to_number();                 
                        \
-       }                                                                       
                                                                \
-       else if (a.is_bool() && b.is_bool())                                    
                        \
-               store = a.to_bool() == b.to_bool();                             
                                \
-}                                                                              
   /* end of ABSTRACT_EQUALITY */
-
-#define JUMPIF(jtruth)                                                         
                                        \
-{                                                                              
                                                                \
-       int32t jumpOffset = mStream->read_S24();                                
                        \
-       if (jtruth)                                                             
                                                        \
-               mStream->seekBy(jumpOffset);                                    
                                \
-       break;                                                                  
                                                        \
-}                                                                              
                          /* end of JUMPIF */
-
-void
-ActionMachine::execute()
-{
-       for ( ; ; )
-       {
-
-       if (mStream->isAS3())
-       {
-       switch ((opcode = mStream->read_as3op())) // Assignment intentional
-       {
-       default:
-               throw ASException();
-       case 0:
-       {
-// This is not actually an opcode -- it occurs when the stream is
-// empty. We may need to return from a function, or we may be done.
-               break;
-       }
-/// 0x01 ABC_ACTION_BKPT
-/// Do: Enter the debugger if one has been invoked.
-/// This is a no-op. Enable it if desired.
-/// 0x02 ABC_ACTION_NOP
-/// Do: Nothing.
-/// 0xF3 ABC_ACTION_TIMESTAMP
-       case SWF::ABC_ACTION_NOP:
-       case SWF::ABC_ACTION_BKPT:
-       case SWF::ABC_ACTION_TIMESTAMP:
-       {
-               break;
-       }
-/// 0x03 ABC_ACTION_THROW
-/// Stack In:
-///  obj -- an object
-/// Stack Out:
-///  .
-/// Do: Throw obj as an exception
-/// Equivalent: ACTIONTHROW
-       case SWF::ABC_ACTION_THROW:
-       {
-               throw ASException(mStack.pop());
-               break;
-       }
-/// 0x04 ABC_ACTION_GETSUPER
-/// Stream:
-///  name_id -- V32 index to multiname 'name'
-/// Stack In:
-///  [ns [n]] -- Namespace stuff.
-///  obj -- an object
-/// Stack Out:
-///  obj.super.name
-///  May be the same as the value of obj.name (E.g. inherited variables)
-       case SWF::ABC_ACTION_GETSUPER:
-       {
-               // Get the name.
-               asName a = mStream->read_V32();
-               // Finish it, if necessary.
-               mStack.drop(completeName(a));
-               // Get the target object.
-               as_value vobj& = mStack.top(0);
-               asClass *pClass = findSuper(vobj, true);
-               // If we don't have a class yet, throw.
-               if (!pClass)
-                       throw ASReferenceError();
-               // getMember will throw any necessary exceptions and do the 
push.
-               getMember(pClass, a, vobj);
-               break;
-       }
-/// 0x05 ABC_ACTION_SETSUPER
-/// Stream: UV32 index to multiname 'name'
-/// Stack In:
-///  val -- an object
-///  [ns [n]] -- Namespace stuff.
-///  obj -- an object
-/// Stack Out:
-///  .
-/// Do: Set obj.super.name to val, if allowable.
-       case SWF::ABC_ACTION_SETSUPER:
-       {
-               // Get and finish the name.
-               asName a = mStream->read_V32();
-               as_value vobj = mStack.pop(); // The value
-
-               mStack.drop(completeName(a));
-
-               as_value target = mStack.pop();
-               asClass *pClass = findSuper(target, true);
-               if (!pClass)
-                       throw ASReferenceError();
-
-               setMember(pClass, a, target, vobj);
-               break;
-       }
-/// 0x06 ABC_ACTION_DXNS
-/// Default XML Namespace
-/// Stream: UV32 index to string pool 'nsname'
-/// Do: Create a new public namespace with name nsname, and make this the
-///  default XML namespace. 
-       case SWF::ABC_ACTION_DXNS:
-       {
-               uint32_t soffset = mStream->read_V32();
-               std::string& uri = pool_string(soffset);
-               mDefaultXMLNamespace = mCH->anonNamespace(mST.find(uri));
-               break;
-       }
-/// 0x07 ABC_ACTION_DXNSLATE
-/// Stack In:
-///  nsname -- a string object
-/// Stack Out:
-///  .
-/// Do: Same as ABC_ACTION_DXNS, but the uri is in the stack, not the stream.
-       case SWF::ABC_ACTION_DXNSLATE:
-       {
-               ENSURE_STRING(mStack.top(0));
-               const std::string& uri = mStack.top(0).to_string();
-               mDefaultXMLNamespace = mCH->anonNamespace(mST.find(uri));
-               mStack.drop(1);
-               break;
-       }
-/// 0x08 ABC_ACTION_KILL
-/// Stream: UV32 frame pointer offset 'offset'
-/// Frame: 
-///  Kill at offset
-/// Equivalent: ACTION_DELETE
-       case SWF::ABC_ACTION_KILL:
-       {
-               uint32_t regNum = mStream->read_V32();
-               mFrame.value(regnum).set_undefined();
-               break;
-       }
-/// 0x09 ABC_ACTION_LABEL
-/// Do: Unknown purpose, Tamarin does nothing.
-       case SWF::ABC_ACTION_LABEL:
-       {
-               break;
-       }
-/// 0x0C ABC_ACTION_IFNLT
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If !(a < b) move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFNLT:
-       {
-               bool truth;
-               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), false);
-               mStack.drop(2);
-               JUMPIF(!truth); // truth is: a < b
-               break;
-       }
-/// 0x0D ABC_ACTION_IFNLE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If !(a <= b) move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFNLE:
-       {
-               bool truth;
-               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), true);
-               mStack.drop(2);
-               JUMPIF(truth); // truth is: b < a
-               break;
-       }
-/// 0x0E ABC_ACTION_IFNGT
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If !(a > b) move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFNGT:
-       {
-               bool truth;
-               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), false);
-               mStack.drop(2);
-               JUMPIF(!truth); // truth is: b < a
-               break;
-       }
-/// 0x0F ABC_ACTION_IFNGE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  a -- an object
-///  b -- an object
-/// Stack Out:
-///  .
-/// Do: If !(a >= b) move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFNGE:
-       {
-               bool truth;
-               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), true);
-               mStack.drop(2);
-               JUMPIF(truth); // truth is: a < b
-               break;
-       }
-/// 0x10 ABC_ACTION_JUMP
-/// Stream: S24 jump offset 'jump'
-/// Do: If jump is negative, check for interrupts. Move by jump in stream.
-/// Equivalent: ACTION_BRANCHALWAYS
-       case SWF::ABC_ACTION_JUMP:
-       {
-               JUMPIF(true);
-               break;
-       }
-/// 0x11 ABC_ACTION_IFTRUE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a is 'true', move by jump in stream, as ABC_ACTION_JUMP does.
-/// Equivalent: ACTION_BRANCHIFTRUE
-       case SWF::ABC_ACTION_IFTRUE:
-       {
-               bool truth = mStack.top(0).to_bool();
-               mStack.drop(1);
-               JUMPIF(truth);
-               break;
-       }
-/// 0x12 ABC_ACTION_IFFALSE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a is 'false', move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFFALSE:
-       {
-               bool truth = mStack.top(0).to_bool();
-               mStack.drop(1);
-               JUMPIF(!truth);
-               break;
-       }
-/// 0x13 ABC_ACTION_IFEQ
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a == b (weakly), move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFEQ:
-       {
-               bool truth;
-               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), false);
-               mStack.drop(2);
-               JUMPIF(truth);
-               break;
-       }
-/// 0x14 ABC_ACTION_IFNE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a != b (weakly), move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFNE:
-       {
-               bool truth;
-               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), false);
-               mStack.drop(2);
-               JUMPIF(!truth);
-               break;
-       }
-/// 0x15 ABC_ACTION_IFLT
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a < b move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFLT:
-       {
-               bool truth;
-               ABSTRACT_COMPARE(truth, mStack.top(1), mStack.top(0), false);
-               mStack.drop(2);
-               JUMPIF(truth); // truth is: a < b
-               break;
-       }
-/// 0x16 ABC_ACTION_IFLE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a <= b move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFLE:
-       {
-               bool truth;
-               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), true);
-               mStack.drop(2);
-               JUMPIF(!truth); // truth is: b < a
-               break;
-       }
-/// 0x17 ABC_ACTION_IFGT
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a > b move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFGT:
-       {
-               bool truth;
-               // If b < a, then a > b, with undefined as false
-               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), false);
-               mStack.drop(2);
-               JUMPIF(truth); // truth is: b < a
-               break;
-       }
-/// 0x18 ABC_ACTION_IFGE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a >= b move by jump in stream, as ABC_ACTION_JUMP does.
-       case SWF::ABC_ACTION_IFGE:
-       {
-               bool truth;
-               ABSTRACT_COMPARE(truth, mStack.top(0), mStack.top(1), true);
-               mStack.drop(2);
-               JUMPIF(!truth); // truth is: a < b
-               break;
-       }
-/// 0x19 ABC_ACTION_IFSTRICTEQ
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a == b (strictly), move by jump in stream, as ABC_ACTION_JUMP
-       case SWF::ABC_ACTION_IFSTRICTEQ:
-       {
-               bool truth;
-               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), true);
-               mStack.drop(2);
-               JUMPIF(truth);
-               break;
-       }
-/// 0x1A ABC_ACTION_IFSTRICTNE
-/// Stream: S24 jump offset 'jump'
-/// Stack In:
-///  b -- an object
-///  a -- an object
-/// Stack Out:
-///  .
-/// Do: If a != b (strongly), move by jump in stream, as ABC_ACTION_JUMP
-       case SWF::ABC_ACTION_IFSTRICTNE:
-       {
-               bool truth;
-               ABSTRACT_EQUALITY(truth, mStack.top(1), mStack.top(0), true);
-               mStack.drop(2);
-               JUMPIF(!truth);
-               break;
-       }
-/// 0x18 ABC_ACTION_LOOKUPSWITCH
-/// Stream: 3 bytes | V32 count as 'case_count - 1' | case_count of S24
-///  as 'cases'
-/// Stack In:
-///  index -- an integer object
-/// Stack Out:
-///  .
-/// Do: If index >= case_count, reset stream to position on op entry.
-///  Otherwise, move by cases[index] - 1 from stream position on op entry.
-       case SWF::ABC_ACTION_LOOKUPSWITCH:
-       {
-               AbcHandlers::stream_position npos = mStream->tell();
-               if (!mStack.top(0).is_number())
-                       throw ASMalformedError();
-
-               uint32_t index = mStack.top(0).to_int();
-               mStack.drop(1);
-
-               mStream->seekBy(3); // Skip the intial offset.
-               uint32_t cases = mStream->read_V32();
-               // Read from our original position and use it to skip if the 
case
-               // is out of range.
-               if (index > cases)
-               {
-                       mStream->seekTo(npos);
-                       mStream->seekTo(npos + mStream->read_S24());
-               }
-               else
-               {
-                       mStream->seekTo(npos + 3 * (index + 1));
-                       uint_32t newpos = mStream->read_S24();
-                       mStream->seekTo(npos - 1 + newpos);
-               }
-               break;
-       }
-/// 0x1C ABC_ACTION_PUSHWITH
-/// Stack In:
-///  scope -- a scope
-/// Stack Out:
-///  .
-/// Do: Enter scope with previous scope as its base, unless it already had
-///  a base, in which case leave that alone.
-       case SWF::ABC_ACTION_PUSHWITH:
-       {
-               asScope a = mStack.top(0).to_scope();
-               mStack.drop(1);
-               mScopeStack.push(a);
-               // If there wasn't a base scope, then this becomes it.
-               if (!mBaseScope)
-                       mBaseScope = mCurrentScope;
-               break;
-       }
-/// 0x1D ABC_ACTION_POPSCOPE
-/// Do: exit current scope. Clear the base if the depth is now 
-///  shallower than the base's depth.
-       case SWF::ABC_ACTION_POPSCOPE:
-       {
-               if (mCurrentScope == mBaseScope)
-                       mBaseScope = NULL;
-               mScopeStack.pop();
-               break;
-       }
-/// 0x1E ABC_ACTION_NEXTNAME
-/// Stack In:
-///  index -- an integer object
-///  obj -- an object
-/// Stack Out:
-///  name -- the key name of the property at index in obj
-       case SWF::ABC_ACTION_NEXTNAME:
-       {
-               ENSURE_NUMBER(mStack.top(0));
-               ENSURE_OBJECT(mStack.top(1));
-               as_object *obj = mStack.top(1).to_object();
-               uint32_t index = mStack.top(0).to_uint();
-               mStack.drop(1);
-               asBinding *b = obj->binding_at_index(index);
-               if (next)
-                       mStack.top(0) = b->getNameString();
-               else
-                       mStack.top(0) = "";
-               break;
-       }
-/// 0x1F ABC_ACTION_HASNEXT
-/// Stack In:
-///  index -- an integer object
-///  obj -- an object
-/// Stack Out:
-///  next_index -- next index after index in obj, or 0 if none.
-/// Do: If there is a key/val pair after index, make next_index as it.
-///  Otherwise, make next_index 0.
-       case SWF::ABC_ACTION_HASNEXT:
-       {
-               ENSURE_NUMBER(mStack.top(0));
-               ENSURE_OBJECT(mStack.top(1));
-               as_object *obj = mStack.top(1).to_object();
-               uint32_t index = mStack.top(0).to_uint();
-               mStack.drop(1);
-               asBinding *next = obj->binding_after_index(index);
-               if (next)
-                       mStack.top(0) = next->getDispatch();
-               else
-                       mStack.top(0) = 0;
-               break;
-       }
-/// 0x20 ABC_ACTION_PUSHNULL
-/// Stack Out:
-///  n -- a Null object.
-       case SWF::ABC_ACTION_PUSHNULL:
-       {
-               mStack.grow(1);
-               mStack.top(0).set_null();
-               break;
-       }
-/// 0x21 ABC_ACTION_PUSHUNDEFINED
-/// Stack Out:
-///  n -- an Undefined object.
-       case SWF::ABC_ACTION_PUSHUNDEFINED:
-       {
-               mStack.grow(1);
-               mStack.top(0).set_undefined();
-               break;
-       }
-/// 0x23 ABC_ACTION_NEXTVALUE
-/// Stack In:
-///  index -- an integer object
-///  obj -- an object (namespaces okay)
-/// Stack Out:
-///  value -- the value of the key value pair in obj at index.
-       case SWF::ABC_ACTION_NEXTVALUE:
-       {
-               ENSURE_NUMBER(mStack.top(0));
-               ENSURE_OBJECT(mStack.top(1));
-               as_object *obj = mStack.top(1).to_object();
-               uint32_t index = mStack.top(0).to_uint();
-               asBinding *b = obj->binding_at_index(index);
-               mStack.drop(1);
-               if (!next)
-                       mStack.top(0).set_undefined();
-               else // The top of the stack is obj, as it should be.
-                       pushCall(1, &mStack.top(0), b);
-               break;
-       }
-/// 0x24 ABC_ACTION_PUSHBYTE
-/// Stream: S8 as 'byte'
-/// Stack Out:
-///  byte -- as a raw byte
-       case SWF::ABC_ACTION_PUSHBYTE:
-       {
-               int8_t *b = mStream->read_s8();
-               mStack.grow(1);
-               mStack.top(0) = b;
-               break;
-       }
-/// 0x25 ABC_ACTION_PUSHSHORT
-/// Stream: V32 as 'value'
-/// Stack Out:
-///  value -- as a raw integer
-       case SWF::ABC_ACTION_PUSHSHORT:
-       {
-               signed short s = static_cast<signed short>(mStream->read_V32());
-               mStack.grow(1);
-               mStack.top(0) = s;
-               break;
-       }
-/// 0x26 ABC_ACTION_PUSHTRUE
-/// Stack Out:
-///  true -- the True object
-       case SWF::ABC_ACTION_PUSHTRUE:
-       {
-               mStack.grow(1);
-               mStack.top(0).set_bool(true);
-               break;
-       }
-/// 0x27 ABC_ACTION_PUSHFALSE
-/// Stack Out:
-///  false -- the False object
-       case SWF::ABC_ACTION_PUSHFALSE:
-       {
-               mStack.grow(1);
-               mStack.top(0).set_bool(false);
-               break;
-       }
-/// 0x28 ABC_ACTION_PUSHNAN
-/// Stack Out:
-///  NaN -- the NaN object
-       case SWF::ABC_ACTION_PUSHNAN:
-       {
-               mStack.grow(1);
-               mStack.top(0).set_nan();
-               break;
-       }
-/// 0x29 ABC_ACTION_POP
-/// Stack In:
-///  a -- anything
-/// Stack Out:
-///  .
-       case SWF::ABC_ACTION_POP:
-       {
-               mStack.drop(1);
-               break;
-       }
-/// 0x2A ABC_ACTION_DUP
-/// Stack In:
-///  a -- anything
-/// Stack Out:
-///  a
-///  a
-       case SWF::ABC_ACTION_DUP:
-       {
-               mStack.grow(1);
-               mStack.top(0) = mStack.top(1);
-               break;
-       }
-/// 0x2B ABC_ACTION_SWAP
-/// Stack In:
-///  a -- anything
-///  b -- anything
-/// Stack Out:
-///  b
-///  a
-       case SWF::ABC_ACTION_SWAP:
-       {
-               as_value inter = mStack.top(0);
-               mStack.top(0) = mStack.top(1);
-               mStack.top(1) = inter;
-               break;
-       }
-/// 0x2C ABC_ACTION_PUSHSTRING
-/// Stream: V32 string pool index 'index'
-/// Stack Out:
-///  value -- String object from string_pool[index]
-       case SWF::ABC_ACTION_PUSHSTRING:
-       {
-               mStack.grow(1);
-               mStack.top(0) = pool_string(mStream->read_V32());
-               break;
-       }
-/// 0x2D ABC_ACTION_PUSHINT
-/// Stream: V32 int pool index 'index'
-/// Stack Out:
-///  value -- Integer object from integer_pool[index]
-       case SWF::ABC_ACTION_PUSHINT:
-       {
-               mStack.grow(1);
-               mStack.top(0) = pool_int(mStream->read_V32());
-               break;
-       }
-/// 0x2E ABC_ACTION_PUSHUINT
-/// Stream: V32 uint pool index 'index'
-/// Stack Out:
-///  value -- Unsigned Integer object from unsigned_integer_pool[index]
-       case SWF::ABC_ACTION_PUSHUINT:
-       {
-               mStack.grow(1);
-               mStack.top(0) = pool_uint(mStream->read_V32());
-               break;
-       }
-/// 0x2F ABC_ACTION_PUSHDOUBLE
-/// Stream: V32 double pool index 'index'
-/// Stack Out:
-///  value -- Double object from double_pool[index]
-       case SWF::ABC_ACTION_PUSHDOUBLE:
-       {
-               mStack.grow(1);
-               mStack.top(0) = pool_double(mStream->read_V32());
-               break;
-       }
-/// 0x30 ABC_ACTION_PUSHSCOPE
-/// Stack In:
-///  scope -- a scope
-/// Stack Out:
-///  .
-/// Do: Enter scope without altering base.
-       case SWF::ABC_ACTION_PUSHSCOPE:
-       {
-               asScope = mStack.top(0).to_scope();
-               mStack.drop(1);
-               pushScope(asScope);
-               break;
-       }
-/// 0x31 ABC_ACTION_PUSHNAMESPACE
-/// Stream: V32 namespace pool index 'index'
-/// Stack Out:
-///  ns -- Namespace object from namespace_pool[index]
-       case SWF::ABC_ACTION_PUSHNAMESPACE:
-       {
-               asNamespace *ns = pool_namespace(mStream->read_V32());
-               mStack.grow(1);
-               mStack.top(0) = *ns;
-               break;
-       }
-/// 0x32 ABC_ACTION_HASNEXT2
-/// Stream: V32 frame location 'objloc' | V32 frame location 'indexloc'
-/// Stack Out:
-///  truth -- True if frame[objloc] has key/val pair after frame[indexloc],
-///   following delagates (__proto__) objects if needed. False, otherwise.
-/// Frame:
-///  Change at objloc to object which possessed next value.
-///  Change at indexloc to index (as object) of the next value.
-       case ABC_ACTION_HASNEXT2:
-       {
-               int32_t oindex = mStream->read_V32();
-               int32_t iindex = mStream->read_V32();
-               as_value &objv = mFrame.value(oindex);
-               as_value &indexv = mFrame.value(iindex);
-               ENSURE_OBJECT(objv);
-               ENSURE_NUMBER(indexv);
-               as_object *obj = objv.to_object();
-               int32_t index = indexv.to_int();
-               asBinding *next = obj->next_after_index(index);
-               mStack.grow(1);
-               if (next)
-               {
-                       mStack.top(0).set_bool(true);
-                       mFrame.value(oindex) = next->getOwner();
-                       mFrame.value(iindex) = next->getName();
-               }
-               else
-               {
-                       mStack.top(0).set_bool(false);
-                       mFrame.value(oindex).set_null();
-                       mFrame.value(iindex) = 0;
-               }
-               break;
-       }
-/// 0x40 ABC_ACTION_NEWFUNCTION
-/// Stream: V32 'index'
-/// Stack Out:
-///  func -- the function object
-/// Do: Information about function is in the pool at index. Construct the
-///  function from this information and bind the current scope.
-       case SWF::ABC_ACTION_NEWFUNCTION:
-       {
-               mStack.grow(1);
-               asMethod *m = pool_method(mStream->read_V32());
-               mStack.top(0) = m->construct(mCurrentScope);
-               break;
-       }
-/// 0x41 ABC_ACTION_CALL
-/// Stream: V32 'arg_count'
-/// Stack In:
-///  argN ... arg1 -- the arg_count arguments to pass
-///  obj -- the object to which the function belongs
-///  func -- the function to be called
-/// Stack Out:
-///  value -- the value returned by obj->func(arg1, ...., argN)
-       case SWF::ABC_ACTION_CALL:
-       {
-               uint32_t argc = mStream->read_V32();
-               as_function *f = mStack.top(argc + 1).to_function();
-               // argc + 1 will be dropped, and mStack.top(argc + 1)
-               // will be the top of the stack, so that is where the
-               // return value should go. (Currently it is the func)
-               pushCall(argc + 1, &mStack.top(argc + 1), asBinding(f));
-               break;
-       }
-/// 0x42 ABC_ACTION_CONSTRUCT
-/// Stream: V32 'arg_count'
-/// Stack In:
-///  argN ... arg1 -- the arg_count arguments to pass
-///  function -- constructor for the object to be constructed
-/// Stack Out:
-///  value -- obj after it has been constructed as obj(arg1, ..., argN)
-       case SWF::ABC_ACTION_CONSTRUCT:
-       {
-               uint32_t argc = mStream->read_V32();
-               as_function *f = mStack.top(argc).to_function();
-               pushCall(argc, &mStack.top(argc), asBinding(f));
-               break;
-       }
-/// 0x43 ABC_ACTION_CALLMETHOD
-/// Stream: V32 'method_id + 1' | V32 'arg_count'
-/// Stack In:
-///  argN ... arg1 -- the arg_count arguments to pass
-///  obj -- the object to be called
-/// Stack Out:
-///  value -- the value returned by obj::'method_id'(arg1, ..., argN)
-       case SWF::ABC_ACTION_CALLMETHOD:
-       {
-               uint32_t dispatch_id = mStream->read_V32() - 1;
-               uint32_t argc = mStream->read_V32();
-               ENSURE_OBJECT(mStack.top(argc));
-               as_object *obj = mStack.top(argc).to_object();
-               asBinding *b = obj.find_at_index(dispatch_id);
-               if (!b)
-               {
-                       mStack.drop(argc);
-                       mStack.top(0).set_undefined();
-                       break;
-               }
-               pushCall(argc + 1, &mStack.top(argc), b);
-               break;
-       }
-/// 0x44 ABC_ACTION_CALLSTATIC
-/// Stream: V32 'method_id' | V32 'arg_count'
-/// Stack In:
-///  argN ... arg1 -- the arg_count arguments to pass
-///  obj -- the object to act as a receiver for the static call
-/// Stack Out:
-///  value -- the value returned by obj->ABC::'method_id'(arg1, ..., argN)
-       case SWF::ABC_ACTION_CALLSTATIC:
-       {
-               asMethod *m = pool_method(mStream->read_V32());
-               uint32_t argc = mStream->read_V32();
-               pushCall(argc + 1, &mStack.top(argc), asBinding(m));
-               break;
-       }
-/// 0x45 ABC_ACTION_CALLSUPER
-/// 0x4E ABC_ACTION_CALLSUPERVOID
-/// Stream: V32 'name_offset' | V32 'arg_count'
-/// Stack In:
-///  [ns [n]] -- Namespace stuff
-///  argN ... arg1 -- the arg_count arguments to pass
-///  obj -- the object whose super is to be called
-/// Stack Out:
-///  0x45: value -- the value returned by 
obj::(resolve)'name_offset'::super(arg1,
-///   ..., argN)
-///  0x4E: .
-       case SWF::ABC_ACTION_CALLSUPER:
-       case SWF::ABC_ACTION_CALLSUPERVOID:
-       {
-               asName a = mStream->read_V32();
-               uint32_t argc = mStream->read_V32();
-               int dropsize = completeName(a);
-               ENSURE_OBJECT(mStack.top(argc + dropsize));
-               mStack.drop(dropsize);
-               asBinding *b = mStack.top(argc).to_object().get_named_super(a);
-               if (opcode == SWF::ABC_ACTION_CALLSUPER)
-                       pushCall(argc + 1, &mStack.top(argc), b);
-               else
-                       pushCall(argc + 1, &mIgnoreReturn, b);
-               break;
-       }
-/// 0x46 ABC_ACTION_CALLPROPERTY
-/// 0x4C ABC_ACTION_CALLPROPLEX
-/// 0x4F ABC_ACTION_CALLPROPVOID
-/// Stream: V32 'name_offset' | V32 'arg_count'
-/// Stack In:
-///  argN ... arg1 -- the arg_count arguments to pass
-///  [ns [n]] -- Namespace stuff
-///  obj -- The object whose property is to be accessed.
-/// Stack Out:
-///  value -- the value from obj::(resolve)'name_offset'(arg1, ..., argN)
-///  (unless ABC_ACTION_CALL_PROPVOID, then: . )
-/// NB: Calls getter/setter if they exist.
-/// If the opcode is ABC_ACTION_CALLPROPLEX, obj is not altered by 
getter/setters
-       case SWF::ABC_ACTION_CALLPROPERTY:
-       case SWF::ABC_ACTION_CALLPROPLEX:
-       case SWF::ABC_ACTION_CALLPROPVOID:
-       {
-               bool lex_only = (opcode == SWF::ABC_ACTION_CALLPROPLEX);
-               asName a = mStream->read_V32();
-               uint32_t argc = mStream->read_V32();
-               int shift = completeName(a, argc);
-               ENSURE_OBJECT(mStack.top(shift + argc));
-               // Ugly setup. Any name stuff is between the args and the 
object.
-               if (shift)
-               {
-                       uint32_t i = argc;
-                       while (i--)
-                               mStack.top(i + shift) = mStack.top(i);
-                       mStack.drop(shift);
-               }
-               asBinding *b = 
mStack.top(argc).to_object()->getPropertyBinding(a);
-               b->setLexOnly(lex_only);
-               if (opcode == SWF::ABC_ACTION_CALLPROPVOID)
-                       pushCall(argc + 1, &mIgnoreReturn, b);
-               else
-               pushCall(argc + 1, &mStack.top(argc), b);
-               break;
-       }
-/// 0x47 ABC_ACTION_RETURNVOID
-/// Do: Return an undefined object up the callstack.
-       case SWF::ABC_ACTION_RETURNVOID:
-       {
-               // Slot the return.
-               *mGlobalReturn = as_value();
-               // And restore the previous state.
-               restoreState();
-               break;
-       }
-/// 0x48 ABC_ACTION_RETURNVALUE
-/// Stack In:
-///  value -- value to be returned
-/// Stack Out:
-///  .
-/// Do: Return value up the callstack.
-       case SWF::ABC_ACTION_RETURNVALUE:
-       {
-               // Slot the return.
-               *mGlobalReturn = mStack.top(0);
-               // And restore the previous state.
-               restoreState();
-               break;
-       }
-/// 0x49 ABC_ACTION_CONSTRUCTSUPER
-/// Stream: V32 'arg_count'
-/// Stack In:
-///  obj -- the object whose super's constructor should be invoked
-///  arg1 ... argN -- the arg_count arguments
-/// Stack Out:
-///  .
-       case SWF::ABC_ACTION_CONSTRUCTSUPER:
-       {
-               uint32_t argc = mStream->read_V32();
-               ENSURE_OBJECT(mStack.top(argc));
-               as_object *obj = mStack.top(argc).to_object();
-               asBinding *b = obj->getSuperConstructor();
-               pushCall(argc + 1, &mIgnoreReturn, b);
-               break;
-       }
-/// 0x4A ABC_ACTION_CONSTRUCTPROP
-/// Stream: V32 'name_offset' | V32 'arg_count'
-/// Stack In:
-///  argN ... arg1 -- the arg_count arguments to pass
-///  [ns [n]] -- Namespace stuff
-///  obj -- the object whose property should be constructed
-/// Stack Out:
-///  value -- the newly constructed prop from obj::(resolve)
-///   'name_offset'(arg1, ..., argN)
-       case SWF::ABC_ACTION_CONSTRUCTPROP:
-       {
-               asName a = mStream->read_V32();
-               uint32_t argc = mStream->read_V32();
-               int shift = completeName(a, argc);
-               ENSURE_OBJECT(mStack.top(argc + shift));
-               // We have to move the stack if there was a shift.
-               if (shift)
-               {
-                       uint32_t i = argc;
-                       while (i--)
-                               mStack.top(i + shift) = mStack.top(i);
-                       mStack.drop(shift);
-               }
-               as_object *obj = mStack.top(argc).to_object();
-               asBinding *b = obj->getPropertyConstructor(a);
-               pushCall(argc + 1, &mStack.top(0), b);
-               break;
-       }
-/// 0x55 ABC_ACTION_NEWOBJECT
-/// Stream: V32 'arg_count'
-/// Stack In:
-///  prop_value_1 -- a value object
-///  prop_name_1 -- a string
-///  .
-///  . (arg_count value/name pairs in all)
-///  .
-///  prop_value_n -- a value object
-///  prop_name_n -- a string
-/// Stack Out:
-///  obj -- A new object which contains all of the given properties.
-/// NB: This builds an object from its properties, it's not a constructor.
-       case SWF::ABC_ACTION_NEWOBJECT:
-       {
-               as_object *obj = mCH->newOfType(NSV::CLASS_OBJECT);
-               uint32_t argc = mStream->read_V32();
-               int i = argc;
-               while (i--)
-               {
-                       obj->add_property(mStack.top(i * 2 + 1), mStack.top(i * 
2));
-               }
-               mStack.drop(argc * 2 - 1);
-               mStack.top(0) = obj;
-               break;
-       }
-/// 0x56 ABC_ACTION_NEWARRAY
-/// Stream: V32 'array_size'
-/// Stack In:
-///  value_n -- a value
-///  .
-///  . (array_size of these)
-///  .
-///  value_1 -- a value
-/// Stack Out:
-///  array -- an array { value_1, value_2, ..., value_n }
-       case SWF::ABC_ACTION_NEWARRAY:
-       {
-               uint32_t asize = mStream->read_V32();
-               as_object *obj = mCH->newOfType(NSV::CLASS_ARRAY);
-               as_array *array = dynamic_cast<as_array*> (obj);
-               array->resize(asize);
-               uint32_t i = asize;
-               while (i--)
-                       array->set_indexed(i, mStack.value(i));
-               mStack.drop(asize - 1);
-               mStack.top(0) = array;
-               break;
-       }
-/// 0x57 ABC_ACTION_NEWACTIVATION
-/// Stack Out:
-///  vtable -- A new virtual table, which has the previous one as a parent.
-       case SWF::ABC_ACTION_NEWACTIVATION:
-       {
-               // TODO
-               break;
-       }
-/// 0x58 ABC_ACTION_NEWCLASS
-/// Stream: V32 'class_id'
-/// Stack In:
-///  obj -- An object to be turned into a class. Its super is constructed.
-/// Stack Out:
-///  class -- The newly made class, made from obj and the information at
-///   cinits_pool[class_id]
-/// NB: This depends on scope and scope base (to determine lifetime(?))
-       case SWF::ABC_ACTION_NEWCLASS:
-       {
-               uint32_t cid = mStream->read_V32();
-               mStack.top(0) = mCH->newOfId(cid, mStack.top(0));
-               break;
-       }
-/// 0x59 ABC_ACTION_GETDESCENDANTS
-/// Stream: V32 'name_id'
-/// Stack In:
-///  value -- Whose descendants to get
-///  [ns [n]] -- Namespace stuff
-/// Stack Out:
-///  ?
-/// NB: This op seems to always throw a TypeError in Tamarin, though I
-/// assume that it ought to do something to yield a list of
-/// descendants of a class.
-       case SWF::ABC_ACTION_GETDESCENDANTS:
-       {
-               // TODO: Decide or discover what to do with this.
-               break;
-       }
-/// 0x5A ABC_ACTION_NEWCATCH
-/// Stream: V32 'catch_id'
-/// Stack Out:
-///  vtable -- vtable suitable to catch an exception of type in catch_id.
-/// NB: Need more information on how exceptions are set up.
-       case SWF::ABC_ACTION_NEWCATCH:
-       {
-               // TODO: Decide if we need this. (Might be a no-op.)
-               break;
-       }
-/// 0x5D ABC_ACTION_FINDPROPSTRICT
-/// 0x5E ABC_ACTION_FINDPROPERTY
-/// Stream: V32 'name_id'
-/// Stack In:
-///  [ns [n]] -- Namespace stuff
-/// Stack Out:
-///  owner -- object which owns property given by looking up the name_id.
-///  0x5D is the undefined object if not found
-///  0x5E throws a ReferenceError if not found
-       case SWF::ABC_ACTION_FINDPROPSTRICT:
-       case SWF::ABC_ACTION_FINDPROPERTY:
-       {
-               asName a = mStream->read_V32();
-               mStack.drop(completeName(a));
-               as_value v = findProperty(a);
-               if ((opcode == SWF::ABC_ACTION_FINDPROPSTRICT) && 
v.is_undefined())
-                       throw ASReferenceException();
-               break;
-       }
-/// 0x5F ABC_ACTION_FINDDEF
-/// Stream: V32 'name_id' (no ns expansion)
-/// Stack Out:
-///  def -- The definition of the name at name_id.
-       case SWF::ABC_ACTION_FINDDEF:
-       {
-               asName a = mStream->read_V32();
-               // TODO
-               break;
-       }
-/// 0x60 ABC_ACTION_GETLEX
-/// Stream: V32 'name_id' (no ns expansion)
-/// Stack Out:
-///  property -- The result of 0x5D (ABC_ACTION_FINDPROPSTRICT)
-///   + 0x66 (ABC_ACTION_GETPROPERTY)
-       case SWF::ABC_ACTION_GETLEX
-       {
-               asName a = mStream->read_V32();
-               as_value v = findProperty(a);
-               if (v.is_undefined())
-                       throw ASReferenceException();
-               mStack.grow(1);
-               mStack.top(0) = v.getProperty(a);
-               break;
-       }
-/// 0x61 ABC_ACTION_SETPROPERTY
-/// Stream: V32 'name_id'
-/// Stack In:
-///  value -- The value to be used
-///  [ns [n]] -- Namespace stuff
-///      OR
-///  [key] -- Key name for property. Will not have both Namespace and key.
-///  obj -- The object whose property is to be set
-/// Stack Out:
-///  .
-/// NB: If the name at name_id is completely qualified, neither a namespace
-/// nor a key is needed.  If the name_id refers to a name with a runtime
-/// namespace, then this will be used.  If neither of those is true and
-/// obj is a dictionary and key is a name, then the name_id is discarded and
-/// key/value is set in the dictionary obj instead.
-       case SWF::ABC_ACTION_SETPROPERTY:
-       {
-               asName a = mStream->read_V32();
-               as_value &v = mStack.pop();
-               if (!a.isRuntime())
-               {
-                       mStack.top(0).setProperty(a, v);
-                       mStack.drop(1);
-               }
-               else
-               {
-                       if (a.isRtns() || !(mStack.top(0).is_object()
-                               && mStack.top(1).is_dictionary()))
-                       {
-                               mStack.drop(completeName(a));
-                               mStack.top(0).setProperty(a, v);
-                               mStack.drop(1);
-                       }
-                       else
-                       {
-                               mStack.top(1).setDictProperty(mStack.top(0), v);
-                               mStack.drop(2);
-                       }
-               }
-               break;
-       }
-/// 0x62 ABC_ACTION_GETLOCAL
-/// Stream: V32 'frame_index'
-/// Frame: value at frame_index is needed
-/// Stack Out:
-///  value
-       case SWF::ABC_ACTION_GETLOCAL:
-       {
-               mStack.grow(1);
-               mStack.top(0) = mFrame.value(mStream->read_V32());
-               break;
-       }
-/// 0x63 ABC_ACTION_SETLOCAL
-/// Stream: V32 'frame_index'
-/// Frame: obj at frame_index is set to value
-/// Stack In:
-///  value
-/// Stack Out:
-///  .
-       case SWF::ABC_ACTION_SETLOCAL:
-       {
-               mFrame.value(mStream->read_V32()) = mStack.top(0);
-               mStack.drop(1);
-               break;
-       }
-/// 0x64 ABC_ACTION_GETGLOBALSCOPE
-/// Stack Out:
-///  global -- The global scope object
-       case SWF::ABC_ACTION_GETGLOBALSCOPE:
-       {
-               mStack.grow(1);
-               mStack.top(0) = mGlobalScope;
-               break;
-       }
-/// 0x65 ABC_ACTION_GETSCOPEOBJECT
-/// Stream: S8 'depth'
-/// Stack Out:
-///  scope -- The scope object at depth
-       case SWF::ABC_ACTION_GETSCOPEOBJECT
-       {
-               uint8_t depth = mStream->read_u8();
-               mStack.grow(1);
-               mStack.top(0) = mScopeStack(depth);
-               break;
-       }
-/// 0x66 ABC_ACTION_GETPROPERTY
-/// Stream: V32 'name_id'
-/// Stack In:
-///  [ns [n]] -- Namespace stuff
-///      OR
-///  [key] -- Key name for property. Will not have both Namespace and key.
-///  obj -- The object whose property is to be retrieved
-/// Stack Out:
-///  prop -- The requested property.
-/// NB: See 0x61 (ABC_ACTION_SETPROPETY) for the decision of ns/key.
-       case SWF::ABC_ACTION_GETPROPERTY:
-       {
-               asName a = mStream->read_V32();
-               if (!a.isRuntime())
-               {
-                       mStack.top(0) = mStack.top(0).getProperty(a, v);
-               }
-               else
-               {
-                       if (a.isRtns() || !(mStack.top(0).is_object()
-                               && mStack.top(1).is_dictionary()))
-                       {
-                               mStack.drop(completeName(a));
-                               mStack.top(0) = mStack.top(0).getProperty(a);
-                       }
-                       else
-                       {
-                               mStack.top(1) = 
mStack.top(1).getDictProperty(mStack.top(0));
-                               mStack.drop(1);
-                       }
-               }
-               break;
-       }
-/// 0x68 ABC_ACTION_INITPROPERTY
-/// Stream V32 'name_id'
-/// Stack In:
-///  value -- The value to be put into the property.
-///  [ns [n]] -- Namespace stuff
-///  obj -- The object whose property is to be initialized
-/// Stack Out:
-///  .
-/// Do:
-///  Set obj::(resolve)'name_id' to value, set bindings from the context.
-       case SWF::ABC_ACTION_INITPROPERTY:
-       {
-               asName a = mStream->read_V32();
-               as_value& v = mStack.pop();
-               mStack.drop(completeName(a));
-               mStack.pop().to_object().setProperty(a, v, true); // true for 
init
-               break;
-       }
-/// 0x6A ABC_ACTION_DELETEPROPERTY
-/// Stream: V32 'name_id'
-/// Stack In:
-///  [ns [n]] -- Namespace stuff
-///  obj -- The object whose property should be deleted.
-/// Stack Out:
-///  truth -- True if property was deleted or did not exist, else False.
-       case SWF::ABC_ACTION_DELETEPROPERTY:
-       {
-               asName a = mStream->read_V32();
-               mStack.drop(completeName(a));
-               mStack.top(0) = mStack.top(0).deleteProperty(a);
-               break;
-       }
-/// 0x6C ABC_ACTION_GETSLOT
-/// Stream: V32 'slot_index + 1'
-/// Stack In:
-///  obj -- The object which owns the desired slot.
-/// Stack Out:
-///  slot -- obj.slots[slot_index]
-       case SWF::ABC_ACTION_GETSLOT
-       {
-               uint32_t sindex = mStream->read_V32();
-               if (!sindex)
-                       throw ASException();
-               --sindex;
-               mStack.top(0) = mStack.top(0).getSlot(sindex);
-               break;
-       }
-/// 0x6D ABC_ACTION_SETSLOT
-/// Stream: V32 'slot_index + 1'
-/// Stack In:
-///  value -- The value intended for the slot.
-///  obj -- The object whose slot should be set.
-/// Stack Out:
-///  .
-/// Do: obj.slots[slot_index] = value
-       case SWF::ABC_ACTION_SETSLOT:
-       {
-               uint32_t sindex = mStream->read_V32();
-               if (!sindex)
-                       throw ASException();
-               --sindex;
-               mStack.top(0).setSlot(sindex, mStack.top(1));
-               mStack.drop(2);
-               break;
-       }
-/// 0x6E ABC_ACTION_GETGLOBALSLOT
-/// Stream: V32 'slot_index + 1'
-/// Stack In:
-///  .
-/// Stack Out:
-///  slot -- globals.slots[slot_index]
-/// NB: Deprecated
-       case SWF::ABC_ACTION_GETGLOBALSLOT:
-       {
-               uint32_t sindex = mStream->read_V32();
-               if (!sindex)
-                       throw ASException();
-               --sindex;
-               mStack.grow(1);
-               mStack.top(0) = mGlobal.getSlot(sindex);
-               break;
-       }
-/// 0x6F ABC_ACTION_SETGLOBALSLOT
-/// Stream: V32 'slot_index + 1'
-/// Stack In:
-///  value -- The value to be placed into the slot.
-/// Stack Out:
-///  .
-/// Do: globals[slot_index] = value
-/// NB: Deprecated
-       case SWF::ABC_ACTION_SETGLOBALSLOT:
-       {
-               uint32_t sindex = mStream->read_V32();
-               if (!sindex)
-                       throw ASException();
-               --sindex;
-               mGlobal.setSlot(sindex, mStack.pop());
-               break;
-       }
-/// 0x70 ABC_ACTION_CONVERT_S
-/// Stack In:
-///  value -- An object
-/// Stack Out:
-///  str_value -- value as a string
-       case SWF::ABC_ACTION_CONVERT_S:
-       {
-               mStack.top(0) = mStack.top(0).to_string();
-               break;
-       }
-/// 0x71 ABC_ACTION_ESC_XELEM
-/// Stack In:
-///  value -- An object to be escaped
-/// Stack Out:
-///  str_value -- value as a string, escaped suitably for an XML element.
-       case SWF::ABC_ACTION_ESC_XELEM:
-       {
-               mStack.top(0) = mStack.top(0).to_escaped_xml_element();
-               break;
-       }
-/// 0x72 ABC_ACTION_ESC_XATTR
-/// Stack In:
-///  value -- An object to be escaped
-/// Stack Out:
-///  str_value -- value as a string, escaped suitably for an XML attribute.
-       case SWF::ABC_ACTION_ESC_XATTR:
-       {
-               mStack.top(0) = mStack.top(0).to_escaped_xml_attribute();
-               break;
-       }
-/// 0x73 ABC_ACTION_CONVERT_I
-/// 0x83 ABC_ACTION_COERCE_I (deprecated)
-/// Stack In:
-///  value -- An object to be converted to Integer
-/// Stack Out:
-///  int_value -- value as an integer object
-       case SWF::ABC_ACTION_CONVERT_I:
-       case SWF::ABC_ACTION_COERCE_I:
-       {
-               mStack.top(0) = mStack.top(0).to_number<int>();
-               break;
-       }
-/// 0x74 ABC_ACTION_CONVERT_U
-/// 0x88 ABC_ACTION_COERCE_U (deprecated)
-/// Stack In:
-///  value -- An object to be converted to unsigned integer
-/// Stack Out:
-///  int_value -- value as an unsigned integer object
-       case SWF::ABC_ACTION_CONVERT_U:
-       case SWF::ABC_ACTION_COERCE_U:
-       {
-               mStack.top(0) = mStack.top(0).to_number<unsigned int>();
-               break;
-       }
-/// 0x75 ABC_ACTION_CONVERT_D
-/// 0x84 ABC_ACTION_COERCE_D (deprecated)
-/// Stack In:
-///  value -- An object to be converted to a double
-/// Stack Out:
-///  double_value -- value as a double object
-       case SWF::ABC_ACTION_CONVERT_D:
-       case SWF::ABC_ACTION_COERCE_D:
-       {
-               mStack.top(0) = mStack.top(0).to_double();
-               break;
-       }
-/// 0x76 ABC_ACTION_CONVERT_B
-/// 0x81 ABC_ACTION_COERCE_B (deprecated)
-/// Stack In:
-///  value -- An object to be converted to a boolean
-/// Stack Out:
-///  bool_value -- value as a boolean object
-       case SWF::ABC_ACTION_CONVERT_B:
-       case SWF::ABC_ACTION_COERCE_B:
-       {
-               mStack.top(0) = mStack.top(0).to_bool();
-               break;
-       }
-/// 0x77 ABC_ACTION_CONVERT_O
-/// Stack In:
-///  obj -- An object
-/// Stack Out:
-///  obj -- An object
-/// Do: If obj is Undefined or Null, throw TypeError
-       case SWF::ABC_ACTION_CONVERT_O:
-       {
-               mStack.top(0) = mStack.top(0).to_object();
-               if (mStack.top(0).is_undefined() || mStack.top(0).is_null())
-                       throw ASTypeException();
-               break;
-       }
-/// 0x78 ABC_ACTION_CHECKFILTER
-/// Stack In:
-///  obj -- An object
-/// Stack Out:
-///  obj -- An object
-/// Do: If obj is not XML based, throw TypeError
-       case SWF::ABC_ACTION_CHECKFILTER:
-       {
-               if (!mStack.top(0).is_xml())
-                       throw ASTypeException();
-               break;
-       }
-/// 0x80 ABC_ACTION_COERCE
-/// Stream: V32 'name_index'
-/// Stack In:
-///  [ns [n]] -- Possibly name/namespace stuff
-///  obj -- An object to be converted
-/// Stack Out:
-///  coerced_obj -- The object as the desired (resolve)'name_index' type.
-       case SWF::ABC_ACTION_COERCE:
-       {
-               asName a = mStream->read_V32();
-               mStack.drop(completeName(a));
-               mStack.top(0) = mStack.top(0).coerce(a);
-               break;
-       }
-/// 0x82 ABC_ACTION_COERCE_A
-/// Stack In:
-///  obj -- An object to be converted
-/// Stack Out:
-///  obj
-/// Do: Nothing. (The 'a' is for atom, and it's unclear if anything is needed.)
-       case SWF::ABC_ACTION_COERCE_A:
-       {
-               break;
-       }
-/// 0x85 ABC_ACTION_COERCE_S
-/// Stack In:
-///  obj -- An object to be converted
-/// Stack Out:
-///  str_obj -- obj as string. nullString object if obj is Null or Undefined
-       case SWF::ABC_ACTION_COERCE_S:
-       {
-               if (mStack.top(0).is_undefined() || mStack.top(0).is_null())
-                       mStack.top(0) = "";
-               else
-                       mStack.top(0) = mStack.top(0).to_string();
-               break;
-       }
-/// 0x86 ABC_ACTION_ASTYPE
-/// Stream: V32 'name_index'
-/// Stack In:
-///  [ns [n]] -- Possible namespace stuff
-///  obj -- An object to be checked
-/// Stack Out:
-///  cobj -- obj if obj is of type (resolve)'name_index', otherwise Null
-       case SWF::ABC_ACTION_ASTYPE:
-       {
-               asName a = mStream->read_V32();
-               mStack.drop(completeName(a));
-               if (!mStack.top(0).conforms_to(a)
-                       mStack.top(0).set_null();
-               break;
-       }
-/// 0x87 ABC_ACTION_ASTYPELATE
-/// Stack In:
-///  valid -- The object whose type is to be matched
-///  obj -- An object to be checked
-/// Stack Out:
-///  cobj -- obj if type of obj conforms to valid, otherwise Null
-       case SWF::ABC_ACTION_ASTYPELATE:
-       {
-               if (!mStack.top(1).conforms_to(mStack.top(0).to_object()))
-                       mStack.top(1).set_null();
-               mStack.drop(1);
-               break;
-       }
-/// 0x89 ABC_ACTION_COERCE_O
-/// Stack In:
-///  obj -- An object
-/// Stack Out:
-///  cobj -- obj if obj is not Undefined, otherwise Null
-       case SWF::ABC_ACTION_COERCE_O:
-       {
-               if (mStack.top(0).is_undefined())
-                       mStack.top(0) = mStack.top(0).to_object();
-               else
-                       mStack.top(0).set_undefined();
-               break;
-       }
-/// 0x90 ABC_ACTION_NEGATE
-/// Stack In:
-///  obj -- An object
-/// Stack Out:
-///  negdouble -- -1.0 * (double) obj
-       case SWF::ABC_ACTION_NEGATE:
-       {
-               mStack.top(0) = -mStack.top(0).to_number();
-               break;
-       }
-/// 0x91 ABC_ACTION_INCREMENT
-/// Stack In:
-///  num -- A number, integer or double
-/// Stack Out:
-///  num + 1
-       case SWF::ABC_ACTION_INCREMENT:
-       {
-               mStack.top(0) = mStack.top(0).to_number() + 1;
-               break;
-       }
-/// 0x92 ABC_ACTION_INCLOCAL
-/// Stream: V32 'frame_addr'
-/// Frame: Load i from frame_addr and increment it.
-       case SWF::ABC_ACTION_INCLOCAL:
-       {
-               uint32_t foff = mStream->read_V32();
-               mFrame.value(foff) = mFrame.value(foff).to_number() + 1;
-               break;
-       }
-/// 0x93 ABC_ACTION_DECREMENT
-/// Stack In:
-///  num -- A number, integer or double
-/// Stack Out:
-///  num - 1
-       case SWF::ABC_ACTION_DECREMENT:
-       {
-               mStack.top(0) = mStack.top(0).to_number() - 1;
-               break;
-       }
-/// 0x94 ABC_ACTION_DECLOCAL
-/// Stream: V32 'frame_addr'
-/// Frame: Load i from frame_addr and decrement it.
-       case SWF::ABC_ACTION_DECLOCAL:
-       {
-               uint32_t foff = mStream->read_V32();
-               mFrame.value(foff) = mFrame.value(foff).to_number() - 1;
-               break;
-       }
-/// 0x95 ABC_ACTION_ABC_TYPEOF
-/// Stack In:
-///  obj -- An object
-/// Stack Out:
-///  type -- typeof(obj) as a string
-       case SWF::ABC_ACTION_ABC_TYPEOF:
-       {
-               mStack.top(0) = mStack.top(0).typeOf();
-               break;
-       }
-/// 0x96 ABC_ACTION_NOT
-/// Stack In:
-///  obj -- An object
-/// Stack Out:
-///  nobj -- A truth object with value !((Boolean) obj)
-       case SWF::ABC_ACTION_NOT:
-       {
-               mStack.top(0).set_bool(!mStack.top(0).to_bool();)
-               break;
-       }
-/// 0x97 ABC_ACTION_BITNOT
-/// Stack In:
-///  obj -- An object
-/// Stack Out:
-///  nint -- ~((Int) obj)
-       case SWF::ABC_ACTION_BITNOT:
-       {
-               mStack.top(0) = ~mStack.top(0).to_number<int>();
-               break;
-       }
-/// 0xA0 ABC_ACTION_ADD        
-/// Stack In:
-/// a
-/// b
-/// Stack Out:
-/// a + b (double if numeric)
-       case SWF::ABC_ACTION_ADD:
-       {
-               mStack.top(1) = mStack.top(1).add(mStack.top(0));
-               mStack.drop(1);
-               break;
-       }
-/// 0xA1 ABC_ACTION_SUBTRACT
-/// Stack In:
-///  a
-///  b
-/// Stack Out:
-///  a - b (double)
-       case SWF::ABC_ACTION_SUBTRACT:
-       {
-               mStack.top(1) = mStack.top(1).to_number() - 
mStack.top(1).to_number();
-               mStack.drop(1);
-               break;
-       }
-/// 0xA2 ABC_ACTION_MULTIPLY
-/// Stack In:
-///  a
-///  b
-/// Stack Out:
-///  a * b (double)
-       case SWF::ABC_ACTION_MULTIPLY:
-       {
-               mStack.top(1) = mStack.top(1).to_number() * 
mStack.top(0).to_number();
-               mStack.drop(1);
-               break;
-       }
-/// 0xA3 ABC_ACTION_DIVIDE
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  a / b (double)
-       case SWF::ABC_ACTION_DIVIDE:
-       {
-               mStack.top(1) = mStack.top(1).to_number() / 
mStack.top(0).to_number();
-               mStack.drop(1);
-               break;
-       }
-/// 0xA4 ABC_ACTION_MODULO
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  a % b (not integer mod, but remainder)
-       case SWF::ABC_ACTION_MODULO:
-       {
-               double result = mStack.top(1).to_number() / 
mStack.top(0).to_number();
-               int trunc_result = static_cast<int> (result);
-               mStack.top(1) = mStack.top(1).to_number<double>() - 
-                       (trunc_result * mStack.top(0).to_number<double>());
-               mStack.drop(1);
-               break;
-       }
-/// 0xA5 ABC_ACTION_LSHIFT
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  a << b
-       case SWF::ABC_ACTION_LSHIFT:
-       {
-               mStack.top(1) = mStack.top(1).to_int() << 
mStack.top(0).to_int();
-               mStack.drop(1);
-               break;
-       }
-/// 0xA6 ABC_ACTION_RSHIFT
-/// Stack In:
-///  a
-///  b
-/// Stack Out:
-///  a >> b
-       case SWF::ABC_ACTION_RSHIFT:
-       {
-               mStack.top(1) = mStack.top(1).to_int() >> 
mStack.top(0).to_int();
-               mStack.drop(1);
-               break;
-       }
-/// 0xA7 ABC_ACTION_URSHIFT
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  ((unsigned) a) >> b
-       case SWF::ABC_ACTION_URSHIFT:
-       {
-               mStack.top(1) = mStack.top(1).to_number<unsigned int>()
-                       >> mStack.top(0).to_number<int>();
-               mStack.drop(1);
-               break;
-       }
-/// 0xA8 ABC_ACTION_BITAND
-///  a
-///  b
-/// Stack Out:
-///  a & b
-       case SWF::ABC_ACTION_BITAND:
-       {
-               mStack.top(1) = mStack.top(1).to_int() & mStack.top(0).to_int();
-               mStack.drop(1);
-               break;
-       }
-/// 0xA9 ABC_ACTION_BITOR
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  a | b
-       case SWF::ABC_ACTION_BITOR:
-       {
-               mStack.top(1) = mStack.top(1).to_int() | mStack.top(0).to_int();
-               mStack.drop(1);
-               break;
-       }
-/// 0xAA ABC_ACTION_BITXOR
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  a ^ b
-       case SWF::ABC_ACTION_BITXOR:
-       {
-               mStack.top(1) = mStack.top(1).to_int() ^ mStack.top(0).to_int();
-               mStack.drop(1);
-               break;
-       }
-/// 0xAB ABC_ACTION_EQUALS
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  truth -- Truth of (a == b) (weakly)
-       case SWF::ABC_ACTION_EQUALS:
-       {
-               mStack.top(1) = mStack.top(1).weak_equals(mStack.top(0));
-               mStack.drop(1);
-               break;
-       }
-/// 0xAC ABC_ACTION_STRICTEQUALS
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  truth -- Truth of (a == b) (strongly, as in 
-///   0x19 (ABC_ACTION_IFSTRICTEQ))
-       case SWF::ABC_ACTION_STRICTEQUALS:
-       {
-               mStack.top(1) = mStack.top(1).strict_equals(mStack.top(0));
-               mStack.drop(1);
-               break;
-       }
-/// 0xAD ABC_ACTION_LESSTHAN
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  truth -- Truth of (a < b)
-       case SWF::ABC_ACTION_LESSTHAN:
-       {
-               mStack.top(1) = mStack.top(1).less_than(mStack.top(0));
-               mStack.drop(1);
-               break;
-       }
-/// 0xAE ABC_ACTION_LESSEQUALS
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  truth -- Truth of (a <= b)
-       case SWF::ABC_ACTION_LESSEQUALS:
-       {
-               mStack.top(1) = mStack.top(1).less_equal(mStack.top(0));
-               mStack.drop(1);
-               break;
-       }
-/// 0xAF ABC_ACTION_GREATERTHAN
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  truth -- Truth of (a > b)
-       case SWF::ABC_ACTION_GREATERTHAN:
-       {
-               mStack.top(1) = mStack.top(1).greater_than(mStack.top(0));
-               mStack.drop(1);
-               break;
-       }
-/// 0xB0 ABC_ACTION_GREATEREQUALS
-/// Stack In:
-///  b
-///  a
-/// Stack Out:
-///  truth -- Truth of (a >= b)
-       case SWF::ABC_ACTION_GREATEREQUALS:
-       {
-               mStack.top(1) = mStack.top(1).greater_equal(mStack.top(0));
-               mStack.drop(1);
-               break;
-       }
-/// 0xB1 ABC_ACTION_INSTANCEOF
-/// Stack In:
-///  super -- An object
-///  val -- An object
-/// Stack Out:
-///  truth -- Truth of "val is an instance of super"
-       case SWF::ABC_ACTION_INSTANCEOF:
-       {
-               if (mStack.top(1).is_null())
-                       mStack.top(1) = false;
-               else // Calling to_object intentionally causes an exception if 
super is not an object.
-                       mStack.top(1) = 
mStack.top(1).conforms_to(mStack.top(0).to_object());
-               mStack.drop(1);
-               break;
-       }
-/// 0xB2 ABC_ACTION_ISTYPE
-/// Stream: V32 'name_id'
-/// Stack In:
-///  [ns] -- Namespace stuff
-///  obj -- An object
-/// Stack Out:
-///  truth -- Truth of "obj is of the type given in (resolve)'name_id'"
-       case SWF::ABC_ACTION_ISTYPE:
-       {
-               asName a = mStream->read_V32();
-               mStack.drop(completeName(a));
-               mStack.top(0).set_bool(mStack.top(0).conforms_to(a));
-       }
-/// 0xB3 ABC_ACTION_ISTYPELATE
-/// Stack In:
-///  type -- A type to match
-///  obj -- An object
-/// Stack Out:
-///  truth -- Truth of "obj is of type"
-       case SWF::ABC_ACTION_ISTYPELATE:
-       {
-               
mStack.top(1).set_bool(mStack.top(1).conforms_to(mStack.top(0)));
-               mStack.drop(1);
-               break;
-       }
-/// 0xB4 ABC_ACTION_IN
-/// Stack In:
-///  obj -- The object to search for it
-///  name -- The name to find
-/// Stack Out:
-///  truth -- True if name is in current namespace or anywhere in object.
-///   Don't look in the namespace if obj is a dictionary.
-/// NB: Since there doesn't seem to be a way to make a dictionary, this
-/// is not done. If there is, fix this lack.
-       case SWF::ABC_ACTION_IN:
-       {
-               
mStack.top(1).set_bool(mStack.top(1).to_object().contains(mStack.top(0)));
-               mStack.drop(1);
-               break;
-       }
-/// 0xC0 ABC_ACTION_INCREMENT_I
-/// See: 0x91 (ABC_ACTION_INCREMENT), but forces types to int, not double
-       case SWF::ABC_ACTION_INCREMENT_I:
-       {
-               mStack.top(0) = mStack.top(0).to_int() + 1;
-               break;
-       }
-/// 0xC1 ABC_ACTION_DECREMENT_I
-/// See: 0x93 (ABC_ACTION_DECREMENT), but forces types to int, not double
-       case SWF::ABC_ACTION_DECREMENT_I:
-       {
-               mStack.top(0) = mStack.top(0).to_number<int>() - 1;
-               break;
-       }
-/// 0xC2 ABC_ACTION_INCLOCAL_I
-/// See: 0x92 (ABC_ACTION_INCLOCAL), but forces types to int, not double
-       case SWF::ABC_ACTION_INCLOCAL_I:
-       {
-               uint32_t foff = mStream->read_V32();
-               mFrame.value(foff) = mFrame.value(foff).to_number<int>() + 1;
-               break;
-       }
-/// 0xC3 ABC_ACTION_DECLOCAL_I
-/// See: 0x94 (ABC_ACTION_DECLOCAL), but forces types to int, not double
-       case SWF::ABC_ACTION_DECLOCAL_I:
-       {
-               uint32_t foff = mStream->read_V32();
-               mFrame.value(foff) = mFrame.value(foff).to_number<int>() - 1;
-               break;
-       }
-/// 0xC4 ABC_ACTION_NEGATE_I
-/// See: 0x90 (ABC_ACTION_NEGATE), but forces type to int, not double
-       case SWF::ABC_ACTION_NEGATE_I:
-       {
-               mStack.top(0) = - mStack.top(0).to_number<int>();
-               break;
-       }
-/// 0xC5 ABC_ACTION_ADD_I
-/// See: 0xA0 (ABC_ACTION_ADD), but forces type to int
-       case SWF::ABC_ACTION_ADD_I:
-       {
-               mStack.top(1) = mStack.top(1).to_number<int>() + 
mStack.top(0).to_number<int>();
-               mStack.drop(1);
-               break;
-       }
-/// 0xC6 ABC_ACTION_SUBTRACT_I
-/// See: 0xA1 (ABC_ACTION_SUBTRACT), but forces type to int
-       case SWF::ABC_ACTION_SUBTRACT_I:
-       {
-               mStack.top(1) = mStack.top(1).to_number<int>() - 
mStack.top(0).to_number<int>();
-               mStack.drop(1);
-               break;
-       }
-/// 0xC7 ABC_ACTION_MULTIPLY_I
-/// See: 0xA2 (ABC_ACTION_MULTIPLY), but forces type to int
-       case SWF::ABC_ACTION_MULTIPLY_I:
-       {
-               mStack.top(1) = mStack.top(0).to_number<int>() * 
mStack.top(1).to_number<int>();
-               mStack.drop(1);
-               break;
-       }
-/// 0xD0 ABC_ACTION_GETLOCAL0
-/// 0xD1 ABC_ACTION_GETLOCAL1
-/// 0xD2 ABC_ACTION_GETLOCAL2
-/// 0xD3 ABC_ACTION_GETLOCAL3
-/// Frame: Load frame[#] as val
-/// Stack Out:
-///  val
-       case SWF::ABC_ACTION_GETLOCAL0:
-       case SWF::ABC_ACTION_GETLOCAL1:
-       case SWF::ABC_ACTION_GETLOCAL2:
-       case SWF::ABC_ACTION_GETLOCAL3:
-       {
-               mStack.grow(1);
-               mStack.top(0) = mFrame.value(opcode - 
SWF::ABC_ACTION_GETLOCAL0);
-               break;
-       }
-/// 0xD4 ABC_ACTION_SETLOCAL0
-/// 0xD5 ABC_ACTION_SETLOCAL1
-/// 0xD6 ABC_ACTION_SETLOCAL2
-/// 0xD7 ABC_ACTION_SETLOCAL3
-/// Frame: Store val as frame[#]
-/// Stack In:
-///  val
-/// Stack Out:
-///  .
-       case SWF::ABC_ACTION_SETLOCAL0:
-       case SWF::ABC_ACTION_SETLOCAL1:
-       case SWF::ABC_ACTION_SETLOCAL2:
-       case SWF::ABC_ACTION_SETLOCAL3:
-       {
-               mFrame.value(opcode - SWF::ABC_ACTION_SETLOCAL0) = 
mStack.top(0);
-               mStack.drop(1);
-               break;
-       }
-
-/// 0xEF ABC_ACTION_DEBUG
-/// Stream: 7 bytes of unknown stuff to be skipped
-/// Do: skip ahead 7 bytes in stream
-       case SWF::ABC_ACTION_DEBUG:
-       {
-               mStream->seekBy(7);
-               break;
-       }
-/// 0xF0 ABC_ACTION_DEBUGLINE
-/// Stream: V32 'line_number'
-/// Do: Nothing, but line_number is for the debugger if wanted.
-       case SWF::ABC_ACTION_DEBUGLINE:
-       {
-               mStream->skip_V32();
-               break;
-       }
-/// 0xF1 ABC_ACTION_DEBUGFILE
-/// Stream: V32 'name_offset'
-/// Do: Nothing. 'name_offset' into string pool is the file name if wanted.
-       case SWF::ABC_ACTION_DEBUGFILE:
-       {
-               mStream->skip_V32();
-               break;
-       }
-/// 0xF2 ABC_ACTION_BKPTLINE
-/// Stream: V32 'line_number'
-/// Do: Enter debugger if present, line_number is the line number in source.
-       case SWF::ABC_ACTION_BKPTLINE:
-       {
-               mStream->skip_V32();
-               break;
-       }
-       } // end of switch statement
-       } // end of AS3 conditional
-       else // beginning of !AS3 (this code is AS2)
-       {
-       switch (opcode)
-       {
-       } // end of switch statement
-       } // end of AS2 conditional (!AS3)
-       } // end of main loop
-} // end of execute function
-
-void
-ActionMachine::getMember(asClass* pDefinition, asBoundName& name,
-       as_value& instance)
-{
-       if (!instance.is_object())
-               throw ASTypeError();
-
-       asBinding *pBinding = pDefinition->findMember(name, instance);
-       if (pBinding->isWriteOnly())
-               throw ASReferenceError();
-
-       if (!pBinding->isGetSet())
-       {
-               mStack.push(pBinding->getFromInstance(instance));
-               return;
-       }
-
-       // This is a getter, so we need to execute it. Even those
-       // written in C++ get called like this, with pushCall handling.
-       // And push the instance ('this')
-       mStack.push(instance);
-       pushCall(1, &mStack.top(0), pBinding->getGetter());
-}
-
-void
-ActionMachine::setMember(asClass *pDefinition, asBoundName& name,
-       as_value& instance, as_value& newvalue)
-{
-       if (!instance.is_object())
-               throw ReferenceError();
-
-       asBinding *pBinding = pDefinition->findMember(name, instance);
-
-       if (pBinding->isReadOnly())
-               throw ASReferenceError();
-
-       if (!pBinding->isGetSet())
-       {
-               pBinding->setInInstance(instance, newvalue);
-               return;
-       }
-
-       // Two parameters -- the target object, the value to set.
-       mStack.push(instance);
-       mStack.push(newvalue);
-       pushCall(2, &mStack.top(1), pBinding->getSetter());
-}
-
-int
-ActionMachine::completeName(asBoundName &name, int offset)
-{
-       int size = 0;
-
-       asUnboundName* uname = mNamePool.at(name.id);
-       if (uname->isRuntime())
-       {
-               as_value obj = mStack.top(offset);
-               if (obj.is_object() && obj.to_object()->isQName())
-                       name.fill(obj.to_object());
-               ++size;
-
-               if (uname->isRuntimeNamespace())
-                       ++size; // Ignore the Namespace.
-       }
-       else if (uname->isRuntimeNamespace())
-       {
-               uname->setNamespace(mStack.top(offset);
-               ++size;
-       }
-       return size;
-}
-
-asClass *
-ActionMachine::findSuper(as_value &v, bool find_for_primitive)
-{
-       if (v.is_undefined() || v.is_null())
-               return NULL;
-
-       if (v.is_object())
-       {
-               asClass *pProto = v.to_object()->getClass();
-               return pProto ? pProto->getSuper() : NULL;
-       }
-
-       if (v.is_number())
-       {
-               return mCH->getClass(NSV::CLASS_NUMBER);
-       }
-
-       // And so on...
-       // TODO: Other primitives
-       return NULL;
-}
-
-void
-ActionMachine::pushCall(unsigned int stack_in, as_value *return_slot,
-       asBinding *pBind)
-{
-       switch (pBind->mType)
-       {
-       default:
-       case asBinding::T_ACCESS:
-       case asBinding::T_CLASS:
-               throw ASException();
-               return;
-       case asBinding::T_VALUE:
-               return_slot = pBind->getValue()->getCurrentValue();
-               return;
-       case asBinding::T_METHOD:
-               break;
-       }
-
-       asMethod *m = pBind->getMethod();
-
-       if (!(m->isNative() || m->hasBody())
-               throw ASException();
-
-       // Here is where the SafeStack shines:
-       // We set the stack the way it should be on return.
-       // If the return slot is the deepest parameter, leave room for it.
-       if (stack_in && (return_slot == &mStack.top(stack_in - 1)))
-               mStack.drop(stack_in - 1);
-       else // The return slot is somewhere else.
-               mStack.drop(stack_in);
-       // We save that state.
-       saveState();
-       // We make the stack appear empty.
-       mStack.fixDownstop();
-       // We grow to reclaim the parameters. Since this is a SafeStack, they
-       // were not lost.
-       mStack.grow(stack_in);
-
-       // Native functions have to be called now.
-       if (m->isNative())
-       {
-               return_slot = m->CallNative(mStack, mGlobalScope);
-               restoreState();
-               return;
-       }
-
-       // The scope stack should be fixed for non-native calls.
-       mScopeStack.fixDownstop();
-       mScopeStack.push(m->getActivation());
-       mCurrentScope = mScopeStack.top(0);
-
-       // We set the stream and return as given in the method and call.
-       mStream = m->getCode();
-       mGlobalReturn = return_slot;
-
-       // When control goes to the main loop of the interpreter, it will
-       // automatically start executing the method.
-}
-
-void
-ActionMachine::restoreState()
-{
-       State &s = mStateStack.top(0);
-       mStack.setAllSizes(s.mStackTotalSize, s.mStackDepth);
-       mScopeStack.setAllSizes(s.mScopeTotalSize, s.mScopeStackDepth);
-       mStream = s.mStream;
-       mDefaultXMLNamespace = s.mDefaultXMLNamespace;
-       mCurrentScope = s.mCurrentScope;
-       mGlobalReturn = s.mGlobalReturn;
-       mStateStack.drop(1);
-}
-
-void
-ActionMachine::saveState()
-{
-       mStateStack.grow(1);
-       State &s = mStateStack.top(0);
-       s.mStackDepth = mStack.getDownstop();
-       s.mStackTotalSize = mStack.getTotalSize();
-       s.mScopeStackDepth = mScopeStack.getDownstop();
-       s.mScopeTotalSize = mScopeStack.getTotalSize();
-       s.mStream = mStream;
-       s.mDefaultXMLNamespace = mDefaultXMLNamespace;
-       s.mCurrentScope = mCurrentScope;
-       s.mGlobalReturn = mGlobalReturn;
-}
-




reply via email to

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