gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/vm/AbcHandlers.cpp


From: Chad Musick
Subject: [Gnash-commit] gnash ChangeLog server/vm/AbcHandlers.cpp
Date: Wed, 03 Oct 2007 17:27:24 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Chad Musick <cmusick>   07/10/03 17:27:24

Modified files:
        .              : ChangeLog 
Added files:
        server/vm      : AbcHandlers.cpp 

Log message:
        In progress code for AS3 interpreter. Doesn't compile. Doesn't work.
        Will probably change quite a lot before becoming functional.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4512&r2=1.4513
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/AbcHandlers.cpp?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4512
retrieving revision 1.4513
diff -u -b -r1.4512 -r1.4513
--- ChangeLog   3 Oct 2007 16:27:24 -0000       1.4512
+++ ChangeLog   3 Oct 2007 17:27:23 -0000       1.4513
@@ -1,3 +1,11 @@
+2007-10-04 Chad Musick <address@hidden>
+
+       * server/vm/AbcHandlers.cpp: New file. This will become the
+         interpreter for AS3, and I hope to convert the ASHandlers class
+         to this style as well, as it offers some significant clarity
+         and performance gainst.  At the moment, this code won't
+         compile, isn't complete, and isn't even consistent.
+
 2007-10-03 Sandro Santilli <address@hidden>
 
        * server/as_value.cpp (to_bool*): assert that OBJECT and FUNCTION

Index: server/vm/AbcHandlers.cpp
===================================================================
RCS file: server/vm/AbcHandlers.cpp
diff -N server/vm/AbcHandlers.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ server/vm/AbcHandlers.cpp   3 Oct 2007 17:27:24 -0000       1.1
@@ -0,0 +1,1820 @@
+//
+//   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
+//
+
+void
+ActionMachine::execute_as3()
+{
+       for ( ; ; )
+       {
+       switch (mStream.read_as3op())
+       {
+/// 0x01 ABC_ACTION_BKPT
+/// Do: Enter the debugger if one has been invoked.
+/// This is a no-op. Enable it if desired.
+       case SWF::ABC_ACTION_BKPT:
+/// 0x02 ABC_ACTION_NOP
+/// Do: Nothing.
+       case SWF::ABC_ACTION_NOP:
+       {
+               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.top(0));
+               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 = read_V32();
+               // Finish it, if necessary.
+               completeName(a);
+               // Get the target object.
+               stackValueType vobj = mStack.top(0);
+               if (!vobj.is_object())
+               {
+                       // Leave the object, let the exception decide what to 
do.
+                       throw ASReferenceException();
+               }
+               as_object *obj = vobj.to_object();
+               // get_named_super will throw any necessary exceptions.
+               mStack.top(0) = obj.get_named_super(a);
+               break;
+       }
+/// 0x05 ABC_ACTION_SETSUPER
+/// Stream: UV32 index to multiname 'name'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff.
+///  obj -- an object
+///  val -- 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 = read_V32();
+               completeName(a);
+               // Get the target object.
+               as_value vobj = mStack.top(0);
+               if (!vobj.is_object())
+               {
+                       asThrow(AS_EXCEPT_REFERENCE_ERROR);
+               }
+               boost::intrusive_ptr<as_object> obj = vobj.to_object();
+               obj.set_named_super(a, mStack.top(1));
+               mStack.drop(2);
+               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 = 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:
+       {
+               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 = read_V32();
+               mFrame.kill(regnum);
+               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 = mStack.top(1).less_than(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(!truth);
+               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 = mStack.top(1).less_equal(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(!truth);
+               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 = mStack.top(1).greater_than(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(!truth);
+               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 = mStack.top(1).greater_equal(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(!truth);
+               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 = mStack.top(1).weak_equals(mStack.top(0));
+               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 = mStack.top(1).weak_nequals(mStack.top(0));
+               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 = mStack.top(1).less_than(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(truth);
+               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 = mStack.top(1).less_equal(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(truth);
+               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 = mStack.top(1).greater_than(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(truth);
+               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 = mStack.top(1).greater_equal(mStack.top(0));
+               mStack.drop(2);
+               jumpIf(truth);
+               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 = mStack.top(1).strict_equals(mStack.top(0));
+               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 = mStack.top(1).strict_nequals(mStack.top(0));
+               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.seekTell();
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               mStack.drop(1);
+
+               mStream.seekSkip(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 + 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 = mStack.top(0).to_scope();
+               mStack.drop(1);
+               pushScope(asScope);
+               // 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:
+       {
+               popScope();
+               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:
+       {
+               as_object *obj = mStack.top(1).to_object();
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               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:
+       {
+               as_object *obj = mStack.top(1).to_object();
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               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:
+       {
+               as_object *obj = mStack.top(1).to_object();
+               uint32_t index = mStack.top(0).to_number<uint32_t>();
+               mStack.drop(1);
+               asBinding *b = obj->binding_at_index(index);
+               if (next)
+                       mStack.top(0) = b->getValue();
+               else
+                       mStack.top(0).set_undefined();
+               break;
+       }
+/// 0x24 ABC_ACTION_PUSHBYTE
+/// Stream: S8 as 'byte'
+/// Stack Out:
+///  byte -- as a raw byte
+       case SWF::ABC_ACTION_PUSHBYTE:
+       {
+               int8_t *b = 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>(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(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(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(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(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(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 = read_V32();
+               int32_t iindex = read_V32();
+               as_object *obj = mFrame.value(oindex).to_object();
+               int32_t index = mFrame.value(iindex).to_number<int32_t>();
+               asBinding *next = obj->next_after_index(index);
+               mStack.grow(1);
+               if (next)
+               {
+                       mStack.top(0) = true;
+                       mFrame.value(oindex) = next->getOwner();
+                       mFrame.value(iindex) = next->getName();
+               }
+               else
+               {
+                       mStack.top(0) = 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, current scope, and base of the scope.
+       case SWF::ABC_ACTION_NEWFUNCTION:
+       {
+               mStack.grow(1);
+               asMethod *m = pool_method(read_V32());
+               mStack.top(0) = m->construct(mCurrentScope, mBaseScope);
+               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 = read_V32();
+               as_function *f = mStack.top(argc + 1).to_function();
+               as_object *obj = mStack.top(argc).to_object();
+               mStack.top(argc + 1) = f.call(obj, mStack);
+               mStack.drop(argc + 1);
+               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 = read_V32();
+               as_function *f = mStack.top(argc).to_function();
+               mStack.top(argc) = f.construct(mStack);
+               mStack.drop(argc);
+               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 = read_V32() - 1;
+               uint32_t argc = read_V32();
+               as_object *obj = mStack.top(argc).to_object();
+               mStack.top(argc) = obj.call_dispatch(dispatch_id);
+               mStack.drop(argc);
+               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(read_V32());
+               uint32_t argc = read_V32();
+               mStack.top(argc) = m->call_static(mStack.top(argc), 
mStack.top(argc - 1));
+               mStack.drop(argc);
+               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 = read_V32();
+               completeName(a);
+       
+               mStack.top(argc) = mStack.top(argc).get_named_super(a)
+                       .call_function(mStack.top(argc - 1));
+               mStack.drop(opcode == SWF::ABC_ACTION_CALL_SUPER ? argc : argc 
+ 1);
+               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 = read_V32();
+               uint32_t argc = read_V32();
+               int shift = completeName(a, argc);
+               // Ugly setup. Any name stuff is between the args and the 
object.
+               as_object *obj = mStack.top(argc + shift).to_object();
+               mStack.top(shift + argc) = obj->call_property(a, 
mStack.top(argc));
+               mStack.drop(shift + argc);
+               if (opcode == SWF::ABC_ACTION_CALLPROPVOID)
+                       mStack.drop(1);
+               break;
+       }
+/// 0x47 ABC_ACTION_RETURNVOID
+/// Do: Return an undefined object up the callstack.
+       case SWF::ABC_ACTION_RETURNVOID:
+       {
+               mReturnStack.grow(1);
+               mReturnStack.top(0).set_undefined();
+               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:
+       {
+               mReturnStack.push(mStack.pop());
+               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 = read_V32();
+               as_object *obj = mStack.top(argc).to_object();
+               obj->super_construct(mStack.top(argc - 1));
+               mStack.drop(argc + 1);
+               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 = read_V32();
+               uint32_t argc = read_V32();
+               int shift = completeName(a, argc);
+               as_object *obj = mStack.top(argc + shift).to_object();
+               mStack.top(argc + shift) = obj->construct_property(a, 
mStack.top(argc));
+               mStack.drop(argc + shift);
+               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 = 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 = read_V32();
+               as_object *obj = mCH->newOfType(NSV::CLASS_ARRAY);
+               as_array *array = dynamic_cast<as_array*> (obj);
+               array->load(mStack.top(asize - 1));
+               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 = 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;
+       }
+/// 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.
+ABC_ACTION_NEWCATCH = 0x5A,
+
+/// Stream: V32 'name_id'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff
+/// Stack Out:
+///  owner -- object which owns property given by looking up the name_id,
+///   or throw a ReferenceError if none exists.
+ABC_ACTION_FINDPROPSTRICT   = 0x5D,
+
+/// Stream: V32 'name_id'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff
+/// Stack Out:
+///  owner -- object which owns property given by looking up the name_id,
+///   or an Undefined object if none exists.
+ABC_ACTION_FINDPROPERTY = 0x5E,
+
+/// Stream: V32 'name_id' (no ns expansion)
+/// Stack Out:
+///  def -- The definition of the name at name_id.
+ABC_ACTION_FINDDEF  = 0x5F,
+
+/// Stream: V32 'name_id' (no ns expansion)
+/// Stack Out:
+///  property -- The result of 0x5D (ABC_ACTION_FINDPROPSTRICT)
+///   + 0x66 (ABC_ACTION_GETPROPERTY)
+ABC_ACTION_GETLEX   = 0x60,
+
+/// Stream: V32 'name_id'
+/// Stack In:
+///  obj -- The object whose property is to be set
+///  [ns [n]] -- Namespace stuff
+///  [key] -- Key name for property. Will not have both Namespace and key.
+///  value -- The value to be used
+/// Stack Out:
+///  .
+/// Do: Set obj::(resolve)'name_id' to value, or set obj::key to value.
+/// NB: I'm not yet clear which should be used when. (Chad)
+ABC_ACTION_SETPROPERTY  = 0x61,
+
+/// 0x62 ABC_ACTION_GETLOCAL
+/// Stream: V32 'frame_index'
+/// Frame: value at frame_index is needed
+/// Stack Out:
+///  value
+void
+AbcHandlers::AbcGetLocal()
+{
+       mStack.grow(1);
+       mStack.top(0) = mFrame.value(read_V32());
+}
+
+/// 0x63 ABC_ACTION_SETLOCAL
+/// Stream: V32 'frame_index'
+/// Frame: obj at frame_index is set to value
+/// Stack In:
+///  value
+/// Stack Out:
+///  .
+void
+AbcHandlers::AbcSetLocal()
+{
+       mFrame.value(read_V32()) = mStack.top(0);
+       mStack.drop(1);
+}
+
+/// Stack Out:
+///  global -- The global scope object
+ABC_ACTION_GETGLOBALSCOPE   = 0x64,
+
+/// Stream: S8 'depth'
+/// Stack Out:
+///  scope -- The scope object at depth
+ABC_ACTION_GETSCOPEOBJECT   = 0x65,
+
+/// Stream: V32 'name_id'
+/// Stack In:
+///  obj -- The object whose property is to be retrieved
+///  [ns [n]] -- Namespace stuff
+///  [key] -- Key name for property. Will not have both Namespace and key.
+/// Stack Out:
+///  prop -- The requested property.
+/// NB: As with 0x61 (ABC_ACTION_SETPROPERTY) it's unclear to me when
+/// key gets used and when the namespace (or nothing) is used.
+ABC_ACTION_GETPROPERTY  = 0x66,
+
+/// Stream V32 'name_id'
+/// Stack In:
+///  [ns [n]] -- Namespace stuff
+///  obj -- The object whose property is to be initialized
+///  value -- The value to be put into the property.
+/// Stack Out:
+///  .
+/// Do:
+///  Set obj::(resolve)'name_id' to value, set bindings from the context.
+ABC_ACTION_INITPROPERTY = 0x68,
+
+/// Stream: V32 'name_id'
+/// Stack In:
+///  obj -- The object whose property should be deleted.
+///  [ns [n]] -- Namespace stuff
+/// Stack Out:
+///  truth -- True if property was deleted or did not exist, else False.
+ABC_ACTION_DELETEPROPERTY   = 0x6A,
+
+/// Stream: V32 'slot_index + 1'
+/// Stack In:
+///  obj -- The object which owns the desired slot.
+/// Stack Out:
+///  slot -- obj.slots[slot_index]
+ABC_ACTION_GETSLOT  = 0x6C,
+
+/// Stream: V32 'slot_index + 1'
+/// Stack In:
+///  obj -- The object whose slot should be set.
+///  value -- The value intended for the slot.
+/// Stack Out:
+///  .
+/// Do: obj.slots[slot_index] = value
+ABC_ACTION_SETSLOT  = 0x6D,
+
+/// Stream: V32 'slot_index + 1'
+/// Stack In:
+///  .
+/// Stack Out:
+///  slot -- globals.slots[slot_index]
+/// NB: Deprecated
+ABC_ACTION_GETGLOBALSLOT= 0x6E,
+
+/// 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
+ABC_ACTION_SETGLOBALSLOT= 0x6F,
+
+/// Stack In:
+///  value -- An object
+/// Stack Out:
+///  str_value -- value as a string
+ABC_ACTION_CONVERT_S   = 0x70,
+
+/// Stack In:
+///  value -- An object to be escaped
+/// Stack Out:
+///  str_value -- value as a string, escaped suitably for an XML element.
+ABC_ACTION_ESC_XELEM   = 0x71,
+
+/// Stack In:
+///  value -- An object to be escaped
+/// Stack Out:
+///  str_value -- value as a string, escaped suitably for an XML attribute.
+ABC_ACTION_ESC_XATTR   = 0x72,
+
+/// Stack In:
+///  value -- An object to be converted to Integer
+/// Stack Out:
+///  int_value -- value as an integer object
+ABC_ACTION_CONVERT_I   = 0x73,
+
+/// Stack In:
+///  value -- An object to be converted to unsigned integer
+/// Stack Out:
+///  int_value -- value as an unsigned integer object
+ABC_ACTION_CONVERT_U   = 0X74,
+
+/// Stack In:
+///  value -- An object to be converted to a double
+/// Stack Out:
+///  double_value -- value as a double object
+ABC_ACTION_CONVERT_D   = 0X75,
+
+/// Stack In:
+///  value -- An object to be converted to a boolean
+/// Stack Out:
+///  bool_value -- value as a boolean object
+ABC_ACTION_CONVERT_B   = 0X76,
+
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  obj -- An object
+/// Do: If obj is Undefined or Null, throw TypeError
+ABC_ACTION_CONVERT_O   = 0X77,
+
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  obj -- An object
+/// Do: If obj is not XML based, throw TypeError
+ABC_ACTION_CHECKFILTER = 0x78,
+
+/// 0x80 ABC_ACTION_COERCE
+/// Stream: V32 'name_index'
+/// Stack In:
+///  obj -- An object to be converted
+/// Stack Out:
+///  coerced_obj -- The object as the desired (resolve)'name_index' type.
+void
+AbcHandlers::AbcCoerce()
+{
+       uint32_t mindex = read_V32();
+       as_value &v = mStack.top(0);
+       // TODO: Finish
+}
+
+/// 0x81 ABC_ACTION_COERCE_B
+/// See: 0x76 (ABC_ACTION_CONVERT_B)
+/// NB: Deprecated
+/// Aliased in interpreter as 0x81
+
+/// 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.)
+void
+AbcHandlers::AbcCoerceA()
+{
+       return;
+}
+
+/// 0x83 ABC_ACTION_COERCE_I
+/// See: 0x73 ABC_ACTION_CONVERT_I
+/// NB: Deprecated
+/// NOMING 20 Aug 2007
+/// Aliased in interpreter as 0x73
+
+/// 0x84 ABC_ACTION_COERCE_D
+/// See: 0x75 ABC_ACTION_CONVERT_D
+/// NB: Deprecated
+/// NOMING 20 Aug 2007
+/// Aliased in interpreter as 0x75
+
+/// 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
+void
+AbcHandlers::AbcCoerceS()
+{
+       if (mStack.top(0).is_undefined() || mStack.top(0).is_null())
+               mStack.top(0) = "";
+       else
+               mStack.top(0) = mStack.top(0).to_string();
+}
+
+/// 0x86 ABC_ACTION_ASTYPE
+/// Stream: V32 'name_index' (no namespace)
+/// Stack In:
+///  obj -- An object to be checked
+/// Stack Out:
+///  cobj -- obj if obj is of type (resolve)'name_index', otherwise Null
+void
+AbcHandlers::AbcAsType()
+{
+       uint32_t mindex = read_V32();
+       if (!mStack.top(0).conforms_to(pool_name(mindex)))
+               mStack.top(0).set_null();
+}
+
+/// 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
+void
+AbcHandlers::AbcAsTypeLate()
+{
+       if (!mStack.top(1).conforms_to(mStack.top(0).to_object()))
+               mStack.top(1).set_null();
+       mStack.drop(1);
+}
+
+/// 0x88 ABC_ACTION_COERCE_U
+/// See: 0x74 (ABC_ACTION_CONVERT_U)
+/// NB: Deprecated
+/// Placed in interpreter as 0x74 duplicate.
+
+/// 0x89 ABC_ACTION_COERCE_O
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  cobj -- obj if obj is not Undefined, otherwise Null
+void
+AbcHandlers::AbcCoerceO()
+{
+       if (mStack.top(0).is_undefined())
+               mStack.top(0) = mStack.top(0).to_object();
+       else
+               mStack.top(0).set_undefined();
+}
+
+/// 0x90 ABC_ACTION_NEGATE
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  negdouble -- -1.0 * (double) obj
+void
+AbcHandlers::AbcNegate()
+{
+       mStack.top(0) = -mStack.top(0).to_number();
+}
+
+/// 0x91 ABC_ACTION_INCREMENT
+/// Stack In:
+///  num -- A number, integer or double
+/// Stack Out:
+///  num2 -- The same value, but new object.
+/// Do:
+///  num = num + 1 (post-increment)
+void
+AbcHandlers::AbcIncrement()
+{
+       mStack.top(0) = mStack.top(0).to_number() + 1;
+}
+
+/// 0x92 ABC_ACTION_INCLOCAL = 0x92,
+/// Stream: V32 'frame_addr'
+/// Frame: Load i from frame_addr and increment it.
+void
+AbcHandlers::AbcIncLocal()
+{
+       uint32_t foff = read_V32();
+       mFrame.value(foff) = mFrame.value(foff).to_number() + 1;
+}
+
+/// ABC_ACTION_DECREMENT= 0x93,
+/// Stack In:
+///  num -- A number, integer or double
+/// Stack Out:
+///  num2 -- The same value, but new object.
+/// Do:
+///  num = num - 1 (post-decrement)
+void
+AbcHandlers::AbcDecrement()
+{
+       mStack.top(0) = mStack.top(0).to_number() - 1;
+}
+
+/// ABC_ACTION_DECLOCAL = 0x94
+/// Stream: V32 'frame_addr'
+/// Frame: Load i from frame_addr and decrement it.
+void
+AbcHandlers::AbcDecLocal()
+{
+       uint32_t foff = read_V32();
+       mFrame.value(foff) = mFrame.value(foff).to_number() - 1;
+}
+
+/// 0x95 ABC_ACTION_ABC_TYPEOF
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  type -- typeof(obj) as a string
+void
+AbcHandlers::AbcTypeof()
+{
+       mStack.top(0) = mStack.top(0).typeOf();
+}
+
+/// 0x96 ABC_ACTION_NOT
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  nobj -- A truth object with value !((Boolean) obj)
+void
+AbcHandlers::AbcNot()
+{
+       mStack.top(0) = !mStack.top(0).to_bool();
+}
+
+/// 0x97 ABC_ACTION_BITNOT
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  nint -- ~((Int) obj)
+void
+AbcHandlers::AbcBitNot()
+{
+       mStack.top(0) = ~mStack.top(0).to_number<int>();
+}
+
+/// 0xA0 ABC_ACTION_ADD        
+/// Stack In:
+/// a
+/// b
+/// Stack Out:
+/// a + b (double if numeric)
+void
+AbcHandlers::AbcAdd()
+{
+       mStack.top(1) = mStack.top(1).add(mStack.top(0));
+       mStack.drop(1);
+}
+
+/// 0xA1 ABC_ACTION_SUBTRACT
+/// Stack In:/// Stack In:
+///  a
+///  b
+/// Stack Out:
+///  a - b (double)
+void
+AbcHandlers::AbcSubtract()
+{
+       mStack.top(1) = mStack.top(1).to_number<double>() - 
mStack.top(1).to_number<double>();
+       mStack.drop(1);
+}
+
+/// 0xA2 ABC_ACTION_MULTIPLY
+/// Stack In:
+///  a
+///  b
+/// Stack Out:
+///  a * b (double)
+void
+AbcHandlers::AbcMultiply()
+{
+       mStack.top(1) = mStack.top(1).to_number<double>() * 
mStack.top(0).to_number<double>();
+       mStack.drop(1);
+}
+
+/// 0xA3 ABC_ACTION_DIVIDE
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a / b (double)
+void
+AbcHandlers::AbcDivide()
+{
+       mStack.top(1) = mStack.top(1).to_number<double>() / 
mStack.top(0).to_number<double>();
+       mStack.drop(1);
+}
+
+/// 0xA4 ABC_ACTION_MODULO
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a % b (not integer mod, but remainder)
+void
+AbcHandlers::AbcModulo()
+{
+       double result = mStack.top(1).to_number<double>() / 
mStack.top(0).to_number<double>();
+       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);
+}
+
+/// 0xA5 ABC_ACTION_LSHIFT
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a << b
+void
+AbcHandlers::AbcLShift()
+{
+       mStack.top(1) = mStack.top(1).to_number<int>() << 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xA6 ABC_ACTION_RSHIFT
+/// Stack In:
+///  a
+///  b
+/// Stack Out:
+///  a >> b
+void
+AbcHandlers::AbcRShift()
+{
+       mStack.top(1) = mStack.top(1).to_number<int>() >> 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xA7 ABC_ACTION_URSHIFT
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  ((unsigned) a) >> b
+void
+AbcHandlers::AbcURShift()
+{
+       mStack.top(1) = mStack.top(1).to_number<unsigned int>() >> 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xA8 ABC_ACTION_BITAND
+///  a
+///  b
+/// Stack Out:
+///  a & b
+void
+AbcHandlers::AbcBitAnd()
+{
+       mStack.top(1) = mStack.top(1).to_number<int>() & 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xA9 ABC_ACTION_BITOR
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a | b
+void
+AbcHandlers::AbcBitOr()
+{
+       mStack.top(1) = mStack.top(1).to_number<int>() | 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xAA ABC_ACTION_BITXOR
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  a ^ b
+void
+AbcHandlers::AbcBitXor()
+{
+       mStack.top(1) = mStack.top(1).to_number<int>() ^ 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xAB ABC_ACTION_EQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a == b) (weakly)
+void
+AbcHandlers::AbcEquals()
+{
+       mStack.top(1) = mStack.top(1).weak_equals(mStack.top(0));
+       mStack.drop(1);
+}
+
+/// 0xAC ABC_ACTION_STRICTEQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a == b) (strongly, as in 
+///   0x19 (ABC_ACTION_IFSTRICTEQ))
+void
+AbcHandlers::AbcStrictEquals()
+{
+       mStack.top(1) = mStack.top(1).strict_equals(mStack.top(0));
+       mStack.drop(1);
+}
+
+/// 0xAD ABC_ACTION_LESSTHAN
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a < b)
+void
+AbcHandlers::AbcLessThan()
+{
+       mStack.top(1) = mStack.top(1).less_than(mStack.top(0));
+       mStack.drop(1);
+}
+
+/// 0xAE ABC_ACTION_LESSEQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a <= b)
+void
+AbcHandlers::AbcLessEquals()
+{
+       mStack.top(1) = mStack.top(1).less_equal(mStack.top(0));
+       mStack.drop(1);
+}
+
+/// 0xAF ABC_ACTION_GREATERTHAN
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a > b)
+void
+AbcHandlers::AbcGreaterThan()
+{
+       mStack.top(1) = mStack.top(1).greater_than(mStack.top(0));
+       mStack.drop(1);
+}
+
+/// 0xB0 ABC_ACTION_GREATEREQUALS
+/// Stack In:
+///  b
+///  a
+/// Stack Out:
+///  truth -- Truth of (a >= b)
+void
+AbcHandlers::AbcGreaterEquals()
+{
+       mStack.top(1) = mStack.top(1).greater_equal(mStack.top(0));
+       mStack.drop(1);
+}
+
+/// 0xB1 ABC_ACTION_INSTANCEOF
+/// Stack In:
+///  super -- An object
+///  val -- An object
+/// Stack Out:
+///  truth -- Truth of "val is an instance of super"
+void
+AbcHandlers::AbcInstanceOf()
+{
+       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);
+}
+
+/// 0xB2 ABC_ACTION_ISTYPE
+/// Stream: V32 'name_id'
+/// Stack In:
+///  obj -- An object
+/// Stack Out:
+///  truth -- Truth of "obj is of the type given in (resolve)'name_id'"
+void
+AbcHandlers::AbcIsType()
+{
+       uint32_t mindex = read_V32();
+       mStack.top(0).to_bool(mStack.top(0).conforms_to(pool_name(mindex)));
+}
+
+/// 0xB3 ABC_ACTION_ISTYPELATE
+/// Stack In:
+///  type -- A type to match
+///  obj -- An object
+/// Stack Out:
+///  truth -- Truth of "obj is of type"
+void
+AbcHandlers::AbcIsTypeLate()
+{
+       mStack.top(1).to_bool(mStack.top(1).conforms_to(mStack.top(0)));
+       mStack.drop(1);
+}
+
+/// 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.
+void
+AbcHandlers::AbcIn()
+{
+       
mStack.top(1).to_bool(mStack.top(1).to_object().contains(mStack.top(0)));
+       mStack.drop(1);
+}
+
+/// 0xC0 ABC_ACTION_INCREMENT_I
+/// See: 0x91 (ABC_ACTION_INCREMENT), but forces types to int, not double
+void
+AbcHandlers::AbcIncrementI()
+{
+       mStack.top(0) = mStack.top(0).to_number<int>() + 1;
+}
+
+/// 0xC1 ABC_ACTION_DECREMENT_I
+/// See: 0x93 (ABC_ACTION_DECREMENT), but forces types to int, not double
+void
+AbcHandlers::AbcDecrementI()
+{
+       mStack.top(0) = mStack.top(0).to_number<int>() - 1;
+}
+
+/// 0xC2 ABC_ACTION_INCLOCAL_I
+/// See: 0x92 (ABC_ACTION_INCLOCAL), but forces types to int, not double
+void
+AbcHandlers::AbcIncLocalI()
+{
+       uint32_t foff = read_V32();
+       mFrame.value(foff) = mFrame.value(foff).to_number<int>() + 1;
+}
+
+/// 0xC3 ABC_ACTION_DECLOCAL_I
+/// See: 0x94 (ABC_ACTION_DECLOCAL), but forces types to int, not double
+void
+AbcHandlers::AbcDecLocalI()
+{
+       uint32_t foff = read_V32();
+       mFrame.value(foff) = mFrame.value(foff).to_number<int>() - 1;
+}
+
+/// 0xC4 ABC_ACTION_NEGATE_I
+/// See: 0x90 (ABC_ACTION_NEGATE), but forces type to int, not double
+void
+AbcHandlers::AbcNegateI()
+{
+       mStack.top(0) = - mStack.top(0).to_number<int>();
+}
+
+/// 0xC5 ABC_ACTION_ADD_I
+/// See: 0xA0 (ABC_ACTION_ADD), but forces type to int
+void
+AbcHandlers::AbcAddI()
+{
+       mStack.top(1) = mStack.top(1).to_number<int>() + 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xC6 ABC_ACTION_SUBTRACT_I
+/// See: 0xA1 (ABC_ACTION_SUBTRACT), but forces type to int
+void
+AbcHandlers::AbcSubtractI()
+{
+       mStack.top(1) = mStack.top(1).to_number<int>() - 
mStack.top(0).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xC7 ABC_ACTION_MULTIPLY_I
+/// See: 0xA2 (ABC_ACTION_MULTIPLY), but forces type to int
+void
+AbcHandlers::AbcMultiplyI()
+{
+       mStack.top(1) = mStack.top(0).to_number<int>() * 
mStack.top(1).to_number<int>();
+       mStack.drop(1);
+}
+
+/// 0xD0 ABC_ACTION_GETLOCAL0
+/// Frame: Load frame[0] as val
+/// Stack Out:
+///  val
+void
+AbcHandlers::AbcGetLocal0()
+{
+       mStack.grow(1);
+       mStack.top(0) = mFrame.value(0);
+}
+
+/// 0xD1 ABC_ACTION_GETLOCAL1
+/// Frame: Load frame[1] as val
+/// Stack Out:
+///  val
+void
+AbcHandlers::AbcGetLocal1()
+{
+       mStack.grow(1);
+       mStack.top(0) = mFrame.value(1);
+}
+
+/// 0xD2 ABC_ACTION_GETLOCAL2
+/// Frame: Load frame[2] as val
+/// Stack Out:
+///  val
+void
+AbcHandlers::AbcGetLocal2()
+{
+       mStack.grow(1);
+       mStack.top(0) = mFrame.value(2);
+}
+
+/// 0xD3 ABC_ACTION_GETLOCAL3
+/// Frame: Load frame[3] as val
+/// Stack Out:
+///  val
+void
+AbcHandlers::AbcGetLocal3()
+{
+       mStack.grow(1);
+       mStack.top(0) = mFrame.value(3);
+}
+
+/// 0xD4 ABC_ACTION_SETLOCAL0
+/// Frame: Store val as frame[0]
+/// Stack In:
+///  val
+/// Stack Out:
+///  .
+void
+AbcHandlers::AbcSetLocal0()
+{
+       mFrame.value(0) = mStack.top(0);
+       mStack.drop(1);
+}
+
+/// 0xD5 ABC_ACTION_SETLOCAL1
+/// Frame: Store val as frame[1]
+/// Stack In:
+///  val
+/// Stack Out:
+///  .
+void
+AbcHandlers::AbcSetLocal1()
+{
+       mFrame.value(1) = mStack.top(0);
+       mStack.drop(1);
+}
+
+/// 0xD6 ABC_ACTION_SETLOCAL2
+/// Frame: Store val as frame[2]
+/// Stack In:
+///  val
+/// Stack Out:
+///  .
+void
+AbcHandlers::AbcSetLocal2()
+{
+       mFrame.value(2) = mStack.top(0);
+       mStack.drop(1);
+}
+
+/// Frame: Store val as frame[3]
+/// Stack In:
+///  val
+/// Stack Out:
+///  .
+/// 0xD7 ABC_ACTION_SETLOCAL3
+void
+AbcHandlers::AbcSetLocal3()
+{
+       mFrame.value(3) = mStack.top(0);
+       mStack.drop(1);
+}
+
+/// 0xEF ABC_ACTION_DEBUG
+/// Stream: 7 bytes of unknown stuff to be skipped
+/// Do: skip ahead 7 bytes in stream
+void
+AbcHandlers::AbcDebug()
+{
+       seekSkip(7);
+}
+
+/// 0xF0 ABC_ACTION_DEBUGLINE
+/// Stream: V32 'line_number'
+/// Do: Nothing, but line_number is for the debugger if wanted.
+void
+AbcHandlers::AbcDebugline()
+{
+       skip_V32();
+       return;
+}
+
+/// 0xF1 ABC_ACTION_DEBUGFILE
+/// Stream: V32 'name_offset'
+/// Do: Nothing. 'name_offset' into string pool is the file name if wanted.
+void
+AbcHandlers::AbcDebugfile()
+{
+       skip_V32();
+       return;
+}
+
+/// 0xF2 ABC_ACTION_BKPTLINE
+/// Stream: V32 'line_number'
+/// Do: Enter debugger if present, line_number is the line number in source.
+void
+AbcHandlers::AbcBkptline()
+{
+       skip_V32();
+       return;
+}
+
+/// Do: Nothing.
+/// 0xF3 ABC_ACTION_TIMESTAMP
+void
+AbcHandlers::AbcTimestamp()
+{
+       return;
+}
+




reply via email to

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