[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/vm/AbcHandlers.cpp serve...
From: |
Chad Musick |
Subject: |
[Gnash-commit] gnash ChangeLog server/vm/AbcHandlers.cpp serve... |
Date: |
Fri, 05 Oct 2007 15:08:12 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Chad Musick <cmusick> 07/10/05 15:08:12
Modified files:
. : ChangeLog
server/vm : AbcHandlers.cpp
Added files:
server/vm : Machine.h
Log message:
More work on the AS3 virtual machine.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4539&r2=1.4540
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/AbcHandlers.cpp?cvsroot=gnash&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/Machine.h?cvsroot=gnash&rev=1.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4539
retrieving revision 1.4540
diff -u -b -r1.4539 -r1.4540
--- ChangeLog 5 Oct 2007 14:19:54 -0000 1.4539
+++ ChangeLog 5 Oct 2007 15:08:12 -0000 1.4540
@@ -1,3 +1,10 @@
+2007-10-06 Chad Musick <address@hidden>
+
+ * server/vm/Machine.h: New File. First iteration (not documented,
+ not compilable) of class definition for VM for ActionScript3
+ blocks.
+ * server/vm/AbcHandlers.cpp: More regularity, some small changes.
+
2007-10-05 Udo Giacomozzi <address@hidden>
* server/sprite_instance.cpp: Allow attachMovie() to accept also
Index: server/vm/AbcHandlers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/vm/AbcHandlers.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- server/vm/AbcHandlers.cpp 4 Oct 2007 10:00:07 -0000 1.2
+++ server/vm/AbcHandlers.cpp 5 Oct 2007 15:08:12 -0000 1.3
@@ -44,7 +44,7 @@
/// Equivalent: ACTIONTHROW
case SWF::ABC_ACTION_THROW:
{
- throw ASException(mStack.top(0));
+ throw ASException(mStack.pop());
break;
}
/// 0x04 ABC_ACTION_GETSUPER
@@ -59,44 +59,42 @@
case SWF::ABC_ACTION_GETSUPER:
{
// Get the name.
- asName a = read_V32();
+ asName a = mStream.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);
+ 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.
+ mStack.top(0) = 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
-/// 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();
+ asName a = mStream.read_V32();
+ as_value vobj = mStack.pop(); // The value
+
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);
+
+ as_value target = mStack.pop();
+ asClass *pClass = findSuper(target, true);
+ if (!pClass)
+ throw ASReferenceError();
+
+ setMember(pClass, a, target, vobj);
break;
}
/// 0x06 ABC_ACTION_DXNS
@@ -106,7 +104,7 @@
/// default XML namespace.
case SWF::ABC_ACTION_DXNS:
{
- uint32_t soffset = read_V32();
+ uint32_t soffset = mStream.read_V32();
std::string& uri = pool_string(soffset);
mDefaultXMLNamespace = mCH->anonNamespace(mST.find(uri));
break;
@@ -131,8 +129,8 @@
/// Equivalent: ACTION_DELETE
case SWF::ABC_ACTION_KILL:
{
- uint32_t regNum = read_V32();
- mFrame.kill(regnum);
+ uint32_t regNum = mStream.read_V32();
+ mFrame.value(regnum).set_undefined();
break;
}
/// 0x09 ABC_ACTION_LABEL
@@ -370,18 +368,18 @@
/// Otherwise, move by cases[index] - 1 from stream position on op entry.
case SWF::ABC_ACTION_LOOKUPSWITCH:
{
- AbcHandlers::stream_position npos = mStream.seekTell();
+ AbcHandlers::stream_position npos = mStream.tell();
uint32_t index = mStack.top(0).to_number<uint32_t>();
mStack.drop(1);
- mStream.seekSkip(3); // Skip the intial offset.
+ 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 + read_S24());
+ mStream.seekTo(npos + mStream.read_S24());
}
else
{
@@ -413,6 +411,8 @@
/// shallower than the base's depth.
case SWF::ABC_ACTION_POPSCOPE:
{
+ if (mCurrentScope == mBaseScope)
+ mBaseScope = NULL;
popScope();
break;
}
@@ -496,7 +496,7 @@
/// byte -- as a raw byte
case SWF::ABC_ACTION_PUSHBYTE:
{
- int8_t *b = read_s8();
+ int8_t *b = mStream.read_s8();
mStack.grow(1);
mStack.top(0) = b;
break;
@@ -507,7 +507,7 @@
/// value -- as a raw integer
case SWF::ABC_ACTION_PUSHSHORT:
{
- signed short s = static_cast<signed short>(read_V32());
+ signed short s = static_cast<signed short>(mStream.read_V32());
mStack.grow(1);
mStack.top(0) = s;
break;
@@ -582,7 +582,7 @@
case SWF::ABC_ACTION_PUSHSTRING:
{
mStack.grow(1);
- mStack.top(0) = pool_string(read_V32());
+ mStack.top(0) = pool_string(mStream.read_V32());
break;
}
/// 0x2D ABC_ACTION_PUSHINT
@@ -592,7 +592,7 @@
case SWF::ABC_ACTION_PUSHINT:
{
mStack.grow(1);
- mStack.top(0) = pool_int(read_V32());
+ mStack.top(0) = pool_int(mStream.read_V32());
break;
}
/// 0x2E ABC_ACTION_PUSHUINT
@@ -602,7 +602,7 @@
case SWF::ABC_ACTION_PUSHUINT:
{
mStack.grow(1);
- mStack.top(0) = pool_uint(read_V32());
+ mStack.top(0) = pool_uint(mStream.read_V32());
break;
}
/// 0x2F ABC_ACTION_PUSHDOUBLE
@@ -612,7 +612,7 @@
case SWF::ABC_ACTION_PUSHDOUBLE:
{
mStack.grow(1);
- mStack.top(0) = pool_double(read_V32());
+ mStack.top(0) = pool_double(mStream.read_V32());
break;
}
/// 0x30 ABC_ACTION_PUSHSCOPE
@@ -634,7 +634,7 @@
/// ns -- Namespace object from namespace_pool[index]
case SWF::ABC_ACTION_PUSHNAMESPACE:
{
- asNamespace *ns = pool_namespace(read_V32());
+ asNamespace *ns = pool_namespace(mStream.read_V32());
mStack.grow(1);
mStack.top(0) = *ns;
break;
@@ -649,8 +649,8 @@
/// 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();
+ int32_t oindex = mStream.read_V32();
+ int32_t iindex = mStream.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);
@@ -678,7 +678,7 @@
case SWF::ABC_ACTION_NEWFUNCTION:
{
mStack.grow(1);
- asMethod *m = pool_method(read_V32());
+ asMethod *m = pool_method(mStream.read_V32());
mStack.top(0) = m->construct(mCurrentScope, mBaseScope);
break;
}
@@ -692,7 +692,7 @@
/// value -- the value returned by obj->func(arg1, ...., argN)
case SWF::ABC_ACTION_CALL:
{
- uint32_t argc = read_V32();
+ uint32_t argc = mStream.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);
@@ -708,7 +708,7 @@
/// value -- obj after it has been constructed as obj(arg1, ..., argN)
case SWF::ABC_ACTION_CONSTRUCT:
{
- uint32_t argc = read_V32();
+ uint32_t argc = mStream.read_V32();
as_function *f = mStack.top(argc).to_function();
mStack.top(argc) = f.construct(mStack);
mStack.drop(argc);
@@ -723,8 +723,8 @@
/// 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();
+ uint32_t dispatch_id = mStream.read_V32() - 1;
+ uint32_t argc = mStream.read_V32();
as_object *obj = mStack.top(argc).to_object();
mStack.top(argc) = obj.call_dispatch(dispatch_id);
mStack.drop(argc);
@@ -739,8 +739,8 @@
/// 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();
+ asMethod *m = pool_method(mStream.read_V32());
+ uint32_t argc = mStream.read_V32();
mStack.top(argc) = m->call_static(mStack.top(argc),
mStack.top(argc - 1));
mStack.drop(argc);
break;
@@ -759,7 +759,7 @@
case SWF::ABC_ACTION_CALLSUPER:
case SWF::ABC_ACTION_CALLSUPERVOID:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
completeName(a);
mStack.top(argc) = mStack.top(argc).get_named_super(a)
@@ -785,8 +785,8 @@
case SWF::ABC_ACTION_CALLPROPVOID:
{
bool lex_only = (opcode == SWF::ABC_ACTION_CALLPROPLEX);
- asName a = read_V32();
- uint32_t argc = read_V32();
+ asName a = mStream.read_V32();
+ uint32_t argc = mStream.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();
@@ -825,7 +825,7 @@
///
case SWF::ABC_ACTION_CONSTRUCTSUPER:
{
- uint32_t argc = read_V32();
+ uint32_t argc = mStream.read_V32();
as_object *obj = mStack.top(argc).to_object();
obj->super_construct(mStack.top(argc - 1));
mStack.drop(argc + 1);
@@ -842,8 +842,8 @@
/// 'name_offset'(arg1, ..., argN)
case SWF::ABC_ACTION_CONSTRUCTPROP:
{
- asName a = read_V32();
- uint32_t argc = read_V32();
+ asName a = mStream.read_V32();
+ uint32_t argc = mStream.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));
@@ -866,7 +866,7 @@
case SWF::ABC_ACTION_NEWOBJECT:
{
as_object *obj = mCH->newOfType(NSV::CLASS_OBJECT);
- uint32_t argc = read_V32();
+ uint32_t argc = mStream.read_V32();
int i = argc;
while (i--)
{
@@ -888,7 +888,7 @@
/// array -- an array { value_1, value_2, ..., value_n }
case SWF::ABC_ACTION_NEWARRAY:
{
- uint32_t asize = read_V32();
+ uint32_t asize = mStream.read_V32();
as_object *obj = mCH->newOfType(NSV::CLASS_ARRAY);
as_array *array = dynamic_cast<as_array*> (obj);
array->load(mStack.top(asize - 1));
@@ -914,7 +914,7 @@
/// NB: This depends on scope and scope base (to determine lifetime(?))
case SWF::ABC_ACTION_NEWCLASS:
{
- uint32_t cid = read_V32();
+ uint32_t cid = mStream.read_V32();
mStack.top(0) = mCH->newOfId(cid, mStack.top(0));
break;
}
@@ -955,7 +955,7 @@
case SWF::ABC_ACTION_FINDPROPSTRICT:
case SWF::ABC_ACTION_FINDPROPERTY:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
completeName(a);
as_value v = findProperty(a);
if ((opcode == SWF::ABC_ACTION_FINDPROPSTRICT) &&
v.is_undefined())
@@ -968,7 +968,7 @@
/// def -- The definition of the name at name_id.
case SWF::ABC_ACTION_FINDDEF:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
// TODO
break;
}
@@ -979,7 +979,7 @@
/// + 0x66 (ABC_ACTION_GETPROPERTY)
case SWF::ABC_ACTION_GETLEX
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
as_value v = findProperty(a);
if (v.is_undefined())
throw ASReferenceException();
@@ -1004,7 +1004,7 @@
/// key/value is set in the dictionary obj instead.
case SWF::ABC_ACTION_SETPROPERTY:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
as_value &v = mStack.pop();
if (!a.isRuntime())
{
@@ -1036,7 +1036,7 @@
case SWF::ABC_ACTION_GETLOCAL:
{
mStack.grow(1);
- mStack.top(0) = mFrame.value(read_V32());
+ mStack.top(0) = mFrame.value(mStream.read_V32());
break;
}
/// 0x63 ABC_ACTION_SETLOCAL
@@ -1048,7 +1048,7 @@
/// .
case SWF::ABC_ACTION_SETLOCAL:
{
- mFrame.value(read_V32()) = mStack.top(0);
+ mFrame.value(mStream.read_V32()) = mStack.top(0);
mStack.drop(1);
break;
}
@@ -1067,7 +1067,7 @@
/// scope -- The scope object at depth
case SWF::ABC_ACTION_GETSCOPEOBJECT
{
- uint8_t depth = read_u8();
+ uint8_t depth = mStream.read_u8();
mStack.grow(1);
mStack.top(0) = mScopeStack(depth);
break;
@@ -1084,7 +1084,7 @@
/// NB: See 0x61 (ABC_ACTION_SETPROPETY) for the decision of ns/key.
case SWF::ABC_ACTION_GETPROPERTY:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
if (!a.isRuntime())
{
mStack.top(0) = mStack.top(0).getProperty(a, v);
@@ -1117,7 +1117,7 @@
/// Set obj::(resolve)'name_id' to value, set bindings from the context.
case SWF::ABC_ACTION_INITPROPERTY:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
as_value& v = mStack.pop();
completeName(a);
mStack.pop().to_object().setProperty(a, v, true); // true for
init
@@ -1132,7 +1132,7 @@
/// truth -- True if property was deleted or did not exist, else False.
case SWF::ABC_ACTION_DELETEPROPERTY:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
completeName(a);
mStack.top(0) = mStack.top(0).deleteProperty(a);
break;
@@ -1145,7 +1145,7 @@
/// slot -- obj.slots[slot_index]
case SWF::ABC_ACTION_GETSLOT
{
- uint32_t sindex = read_V32();
+ uint32_t sindex = mStream.read_V32();
if (!sindex)
throw ASException();
--sindex;
@@ -1162,7 +1162,7 @@
/// Do: obj.slots[slot_index] = value
case SWF::ABC_ACTION_SETSLOT:
{
- uint32_t sindex = read_V32();
+ uint32_t sindex = mStream.read_V32();
if (!sindex)
throw ASException();
--sindex;
@@ -1179,7 +1179,7 @@
/// NB: Deprecated
case SWF::ABC_ACTION_GETGLOBALSLOT:
{
- uint32_t sindex = read_V32();
+ uint32_t sindex = mStream.read_V32();
if (!sindex)
throw ASException();
--sindex;
@@ -1197,7 +1197,7 @@
/// NB: Deprecated
case SWF::ABC_ACTION_SETGLOBALSLOT:
{
- uint32_t sindex = read_V32();
+ uint32_t sindex = mStream.read_V32();
if (!sindex)
throw ASException();
--sindex;
@@ -1316,7 +1316,7 @@
/// coerced_obj -- The object as the desired (resolve)'name_index' type.
case SWF::ABC_ACTION_COERCE:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
completeName(a);
mStack.top(0) = mStack.top(0).coerce(a);
break;
@@ -1353,7 +1353,7 @@
/// cobj -- obj if obj is of type (resolve)'name_index', otherwise Null
case SWF::ABC_ACTION_ASTYPE:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
completeName(a);
if (!mStack.top(0).conforms_to(a)
mStack.top(0).set_null();
@@ -1410,7 +1410,7 @@
/// Frame: Load i from frame_addr and increment it.
case SWF::ABC_ACTION_INCLOCAL:
{
- uint32_t foff = read_V32();
+ uint32_t foff = mStream.read_V32();
mFrame.value(foff) = mFrame.value(foff).to_number() + 1;
break;
}
@@ -1429,7 +1429,7 @@
/// Frame: Load i from frame_addr and decrement it.
case SWF::ABC_ACTION_DECLOCAL:
{
- uint32_t foff = read_V32();
+ uint32_t foff = mStream.read_V32();
mFrame.value(foff) = mFrame.value(foff).to_number() - 1;
break;
}
@@ -1695,7 +1695,7 @@
/// truth -- Truth of "obj is of the type given in (resolve)'name_id'"
case SWF::ABC_ACTION_ISTYPE:
{
- asName a = read_V32();
+ asName a = mStream.read_V32();
completeName(a);
mStack.top(0).set_bool(mStack.top(0).conforms_to(a));
}
@@ -1744,7 +1744,7 @@
/// See: 0x92 (ABC_ACTION_INCLOCAL), but forces types to int, not double
case SWF::ABC_ACTION_INCLOCAL_I:
{
- uint32_t foff = read_V32();
+ uint32_t foff = mStream.read_V32();
mFrame.value(foff) = mFrame.value(foff).to_number<int>() + 1;
break;
}
@@ -1752,7 +1752,7 @@
/// See: 0x94 (ABC_ACTION_DECLOCAL), but forces types to int, not double
case SWF::ABC_ACTION_DECLOCAL_I:
{
- uint32_t foff = read_V32();
+ uint32_t foff = mStream.read_V32();
mFrame.value(foff) = mFrame.value(foff).to_number<int>() - 1;
break;
}
@@ -1827,7 +1827,7 @@
/// Do: skip ahead 7 bytes in stream
case SWF::ABC_ACTION_DEBUG:
{
- seekSkip(7);
+ seekBy(7);
break;
}
/// 0xF0 ABC_ACTION_DEBUGLINE
@@ -1835,7 +1835,7 @@
/// Do: Nothing, but line_number is for the debugger if wanted.
case SWF::ABC_ACTION_DEBUGLINE:
{
- skip_V32();
+ mStream.skip_V32();
break;
}
/// 0xF1 ABC_ACTION_DEBUGFILE
@@ -1843,7 +1843,7 @@
/// Do: Nothing. 'name_offset' into string pool is the file name if wanted.
case SWF::ABC_ACTION_DEBUGFILE:
{
- skip_V32();
+ mStream.skip_V32();
break;
}
/// 0xF2 ABC_ACTION_BKPTLINE
@@ -1851,7 +1851,7 @@
/// Do: Enter debugger if present, line_number is the line number in source.
case SWF::ABC_ACTION_BKPTLINE:
{
- skip_V32();
+ mStream.skip_V32();
break;
}
} // end of switch statement
@@ -1859,3 +1859,27 @@
} // end of main loop
} // end of execute function
+/// Given a value v, find the class object of the superclass of v.
+/// If find_for_primitive is true, then, for example, The value
+/// 1 (a number) will return the Number class object.
+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...
+ return NULL;
+}
+
Index: server/vm/Machine.h
===================================================================
RCS file: server/vm/Machine.h
diff -N server/vm/Machine.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ server/vm/Machine.h 5 Oct 2007 15:08:12 -0000 1.1
@@ -0,0 +1,184 @@
+// Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef GNASH_MACHINE_H
+#define GNASH_MACHINE_H
+
+#include <vector>
+
+#include "as_value.h"
+
+namespace gnash {
+
+class ASException
+{
+};
+
+class StackException : public ASException
+{
+};
+
+template <class T>
+class Stack
+{
+public:
+ T& top(unsigned int i)
+ {
+ if (i >= mDownstop)
+ throw StackException();
+ unsigned int offset = mEnd - i;
+ return mData[offset >> mChunkShift][offset & mChunkMod];
+ }
+
+ T& value(unsigned int i)
+ {
+ if (i >= mDownstop)
+ throw StackException();
+ unsigned int offset = mEnd - mDownstop + i;
+ return mData[offset >> mChunkShift][offset & mChunkMod];
+ }
+
+ void drop(unsigned int i)
+ { if (i >= mDownstop) throw StackException(); mDownstop -= i; mEnd -=
i; }
+
+ void push(const T& t)
+ { grow(1); top(0) = t; }
+
+ void grow(unsigned int i)
+ {
+ if (((mEnd + i) >> mChunkShift) > mData.size())
+ {
+ if (i > (1 << mChunkShift))
+ throw StackException();
+ mData.push_back(new data_vector(1 << mChunkShift));
+ mData.back()->resize(1 << mChunkShift);
+ }
+ mDownstop += i;
+ mEnd += i;
+ }
+
+ unsigned int getDownstop() const
+ { return mDownstop; }
+
+ unsigned int fixDownstop()
+ { unsigned int ret = mDownstop; mDownstop = 0; return ret; }
+
+ void setDownstop(unsigned int i)
+ { if (mDownstop > mEnd) throw StackException(); mDownstop = i; }
+
+ Stack() : mData(), mDownstop(1), mEnd(1)
+ { /**/ }
+
+ ~Stack()
+ {
+ stack_type::iterator i = mData.begin();
+ for ( ; i != mData.end(); ++i)
+ {
+ delete (*i);
+ }
+ }
+
+private:
+ typedef std::vector<T> data_vector;
+ typedef std::vector<data_vector *> stack_type;
+ stack_type mData;
+ unsigned int mDownstop;
+ unsigned int mEnd;
+
+ // If mChunkMod is not a power of 2 less 1, it will not work properly.
+ static const unsigned int mChunkShift = 6;
+ static const unsigned int mChunkMod = (1 << mChunkShift) - 1;
+};
+
+class CodeStream
+{
+public:
+ uint32_t read_V32();
+ uint8_t read_as3op();
+ std::size_t tell();
+ void seekBy(int change);
+ void seekTo(std::size_t set);
+ int32_t read_S24();
+ int8_t read_s8();
+ uint8_t read_u8();
+ void skip_V32();
+};
+
+class FunctionEntry
+{
+public:
+ FunctionEntry(Stack<as_value> *s) : mStack(s)
+ { mStackReset = s->fixDownstop(); }
+
+ ~FunctionEntry()
+ { if (mStack) mStack->setDownstop(mStackReset); }
+
+private:
+ unsigned int mStackReset;
+ Stack<as_value> *mStack;
+};
+
+class Machine
+{
+public:
+ // Flash specific members.
+ /// The character which initiated these actions.
+ character *getTarget();
+
+ /// Set the character which initiated the actions.
+ /// Not null.
+ void setTarget(character* target);
+
+ void completeName(asBindingName&);
+
+ asClass* findSuper(as_value&, bool);
+
+ as_value getMember(asClass*, asBindingName&, as_value&);
+ bool setMember(asClass*, asBindingName&, as_value& target, as_value&
val);
+
+ std::string pool_string(uint32_t);
+ int pool_int(uint32_t);
+ unsigned int pool_uint(uint32_t);
+ double pool_double(uint32_t);
+ asNamespace* pool_namespace(uint32_t);
+ asMethod* pool_method(uint32_t);
+
+ as_value(v) findProperty(asBindingName&);
+
+ void pushScope(asScope*);
+ asScope* popScope();
+
+ void execute_as3();
+
+ void execute_as2();
+
+private:
+ Stack<as_value> mStack;
+ Stack<FunctionEntry> mCallStack;
+ Stack<as_value> mFrame;
+ Stack<asScope*> mScopeStack;
+ CodeStream mStream;
+
+ ClassHierarchy *mCH;
+
+ asNamespace* mDefaultXMLNamespace;
+ asScope *mGlobalScope;
+ asScope *mCurrentScope;
+ asScope *mBaseScope;
+};
+
+} // namespace gnash
+#endif /* GNASH_MACHINE_H */
- [Gnash-commit] gnash ChangeLog server/vm/AbcHandlers.cpp serve...,
Chad Musick <=