CVSROOT: /sources/gnash Module name: gnash Changes by: Chad Musick <cmusick> 07/10/07 05:09:19
Modified files: . : ChangeLog Added files: server/vm : SafeStack.h Log message: A utility class for multiple-stack simulation and memory safe stack access. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4560&r2=1.4561 http://cvs.savannah.gnu.org/viewcvs/gnash/server/vm/SafeStack.h?cvsroot=gnash&rev=1.1 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4560 retrieving revision 1.4561 diff -u -b -r1.4560 -r1.4561 --- ChangeLog 7 Oct 2007 03:19:48 -0000 1.4560 +++ ChangeLog 7 Oct 2007 05:09:18 -0000 1.4561 @@ -1,5 +1,12 @@ 2007-10-07 Chad Musick <[EMAIL PROTECTED]> + * server/vm/SafeStack.h: New file. Complete definition of a stack + which can be used for obtaining references valid for the life of + the stack and has facilities for simulating multiple stacks + in one stack. See the class for documentation. + +2007-10-07 Chad Musick <[EMAIL PROTECTED]> + * server/vm/CodeStream.h: New file. Complete definition of a stream for safely reading code, with necessary reader functions for AS3. Index: server/vm/SafeStack.h =================================================================== RCS file: server/vm/SafeStack.h diff -N server/vm/SafeStack.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ server/vm/SafeStack.h 7 Oct 2007 05:09:19 -0000 1.1 @@ -0,0 +1,131 @@ +// 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_SAFESTACK_H +#define GNASH_SAFESTACK_H + +#include <vector> + +namespace gnash { + +class StackException {/**/}; + +/// A stack in which all references given remain valid while the stack lives. +/// +/// Safe in SafeStack means that you can maintain a reference +/// given by the stack as long as the stack is alive. Since it is a reference, +/// there is no guarantee that it will remain constant, but it is guaranteed +/// that it will remain valid. +/// +/// Access outside of the bounds of the stack will result in a StackException +/// being thrown. +template <class T> +class SafeStack +{ +public: + /// From the top of the stack, get the i'th value down. 0 is the topmost + /// value. + T& top(unsigned int i) + { + if (i >= mDownstop) + throw StackException(); + unsigned int offset = mEnd - i; + return mData[offset >> mChunkShift][offset & mChunkMod]; + } + + /// From the bottom of the stack, get the i'th value up. 0 is the + /// bottommost value. + T& value(unsigned int i) + { + if (i >= mDownstop) + throw StackException(); + unsigned int offset = mEnd - mDownstop + i; + return mData[offset >> mChunkShift][offset & mChunkMod]; + } + + /// Shrink the stack by i entries. Does not invalidate any entries + /// previously given, it just sets the top for pop, push, and top + /// operations. + void drop(unsigned int i) + { if (i >= mDownstop) throw StackException(); mDownstop -= i; mEnd -= i; } + + /// Put a new value onto the top of the stack. The value will be + /// copied. + void push(const T t) + { grow(1); top(0) = t; } + + /// Grow by i entries. Normally this is 1, but there might be sometime + /// when you need more than that. Cannot grow by more than the size + /// of block allocations, which is (1 << mChunkShift) + /// For mChunkShift == 6, this is 64. + void grow(unsigned int i) + { + if (((mEnd + i) >> mChunkShift) > mData.size()) + { + if (i > (1 << mChunkShift)) + throw StackException(); + mData.push_back(new T[1 << mChunkShift]); + } + mDownstop += i; + mEnd += i; + } + + /// Gives the size of the stack which is currently accessible. + unsigned int getDownstop() const + { return mDownstop; } + + /// Makes the stack appear empty to subsequent callers. This can be used + /// to simulate multiple stacks with a single stack, as in function + /// calling. Returns the portion of the stack which is newly inaccessible. + unsigned int fixDownstop() + { unsigned int ret = mDownstop; mDownstop = 0; return ret; } + + /// Makes the stack read to a depth of 'i'. This cannot be more than + /// totalSize() + void setDownstop(unsigned int i) + { if (mDownstop > mEnd) throw StackException(); mDownstop = i; } + + /// The total size of the stack. This is not what can be read. That + /// value is given by getDownstop() + /// + /// This function is probably not what you need for anything except for + /// setting downstops that weren't returned by either fixDownstop() or + /// getDownstop() + unsigned int totalSize() const { return mEnd - 1; } + + /// Default constructor. + SafeStack() : mData(), mDownstop(1), mEnd(1) + { /**/ } + + /// Delete the allocated data. + ~SafeStack() + { + for (unsigned int i = 0; i < mData.size(); ++i) + delete mData[i]; + } + +private: + typedef std::vector<T*> 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; +}; + +} // namespace gnash +#endif /* GNASH_SAFESTACK_H */ _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit