ActionExec.h

Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
00003 // 
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 3 of the License, or
00007 // (at your option) any later version.
00008 // 
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 // 
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017 
00018 #ifndef GNASH_ACTIONEXEC_H
00019 #define GNASH_ACTIONEXEC_H
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "gnashconfig.h"
00023 #endif
00024 
00025 #include "with_stack_entry.h"
00026 #include "as_environment.h" // for ensureStack
00027 #include "smart_ptr.h"
00028 
00029 #include <vector>
00030 
00031 // Forward declarations
00032 namespace gnash {
00033         class action_buffer;
00034         class as_value;
00035         class swf_function;
00036         class ActionExec;
00037 }
00038 
00039 namespace gnash {
00040 
00041 class tryBlock
00042 {
00043 public:
00044         friend class ActionExec;
00045 
00046         enum tryState
00047         {
00048                 TRY_TRY, // In a try block.
00049                 TRY_CATCH, // In a catch block.
00050                 TRY_FINALLY // In a finally block.
00051         };
00052 
00053     tryBlock(size_t cur_off, size_t try_size, size_t catch_size,
00054                 size_t finally_size, std::string catchName, int stack_depth)
00055                 : mCatchOffset(cur_off + try_size),
00056                 mFinallyOffset(cur_off + try_size + catch_size),
00057                 mAfterTriedOffset(cur_off + try_size + catch_size + finally_size),
00058                 mNamed(true), mName(catchName), mReg(), mState(tryBlock::TRY_TRY),
00059                 mThrownFromCatch(), mStackDepth(stack_depth)
00060         {}
00061 
00062         tryBlock(size_t cur_off, size_t try_size, size_t catch_size,
00063                 size_t finally_size, boost::uint8_t register_index, int stack_depth)
00064                 : mCatchOffset(cur_off + try_size),
00065                 mFinallyOffset(cur_off + try_size + catch_size),
00066                 mAfterTriedOffset(cur_off + try_size + catch_size + finally_size),
00067                 mNamed(false), mName(), mReg(register_index),
00068                 mState(tryBlock::TRY_TRY), mThrownFromCatch(),
00069                 mStackDepth(stack_depth)
00070         {}
00071 
00072 private:
00073         size_t mCatchOffset;
00074         size_t mFinallyOffset;
00075         size_t mAfterTriedOffset;
00076         size_t mSavedEndOffset;
00077         bool mNamed;
00078         std::string mName;
00079         boost::uint8_t mReg;
00080         tryState mState;
00081         as_value mThrownFromCatch;
00082         boost::uint32_t mStackDepth;
00083 };
00084 
00086 class ActionExec {
00087 
00088 private: 
00089 
00093         //
00103         void dumpActions(size_t start, size_t end, std::ostream& os);
00104 
00106         // 
00111         const std::vector<with_stack_entry>& getWithStack() const
00112         {
00113                 return with_stack;
00114         }
00115 
00116 
00119         //
00138         void cleanupAfterRun(bool expectInconsistencies=false);
00139 
00141         std::vector<with_stack_entry> with_stack;
00142 
00143         typedef as_environment::ScopeStack ScopeStack;
00144 
00146         ScopeStack _scopeStack;
00147 
00149         //
00162         size_t _with_stack_limit;
00163 
00165         int _function_var;
00166 
00175         const swf_function* _func;
00176 
00178         boost::intrusive_ptr<as_object> _this_ptr;
00179 
00181         size_t _initial_stack_size;
00182 
00184         size_t _initialCallStackDepth;
00185 
00186         character* _original_target;
00187 
00188         std::list<tryBlock> mTryList;
00189 
00190         bool mReturning;
00191 
00193         //
00200         void fixStackUnderrun(size_t required);
00201 
00202         bool _abortOnUnload;
00203 
00206         boost::uint32_t getScriptTimeout();
00207 
00208 public:
00209 
00213         //
00218         void ensureStack(size_t required)
00219         {
00220                 // The stack_size() < _initial_stack_size case should
00221                 // be handled this by stack smashing checks
00222                 assert( env.stack_size() >= _initial_stack_size );
00223 
00224                 size_t slots_left = env.stack_size() - _initial_stack_size;
00225                 if ( slots_left < required )
00226                 {
00227                         fixStackUnderrun(required);
00228                 }
00229         }
00230 
00234         void pushTryBlock(tryBlock& t);
00235 
00238         void pushReturn(const as_value& t);
00239 
00241         //
00244         const action_buffer& code;
00245 
00247         //
00250         size_t pc;
00251 
00253         //
00256         size_t stop_pc;
00257 
00259         size_t next_pc;
00260 
00262         as_environment& env;
00263 
00265         as_value* retval;
00266 
00268         //
00279         ActionExec(const action_buffer& abuf, as_environment& newEnv, bool abortOnUnloaded=true);
00280 
00282         //
00292         ActionExec(const swf_function& func, as_environment& newEnv, as_value* nRetVal, as_object* this_ptr);
00293 
00295         bool isFunction2() { return _function_var==2; }
00296 
00298         bool isFunction() { return _function_var!=0; }
00299 
00301         as_object* getThisPointer();
00302 
00304         //
00307         const ScopeStack& getScopeStack() const
00308         {
00309                 return _scopeStack;
00310         }
00311 
00313         //
00322         size_t getWithStackLimit() const 
00323         {
00324                 return _with_stack_limit;
00325         }
00326 
00328         //
00337         bool pushWithEntry(const with_stack_entry& entry);
00338 
00340         //
00343         void skip_actions(size_t offset);
00344 
00346         //
00351         bool delVariable(const std::string& name);
00352 
00354         //
00364         bool delObjectMember(as_object& obj, const std::string& name);
00365 
00367         //
00372         void setVariable(const std::string& name, const as_value& val);
00373 
00377         //
00382         void setLocalVariable(const std::string& name, const as_value& val);
00383 
00385         //
00390         as_value getVariable(const std::string& name);
00391 
00393         //
00404         as_value getVariable(const std::string& name, as_object** target);
00405 
00407         //
00418         void setObjectMember(as_object& obj, const std::string& name, const as_value& val);
00419 
00421         //
00435         bool getObjectMember(as_object& obj, const std::string& name, as_value& val);
00436 
00438         //
00449         as_object* getTarget();
00450 
00452         void operator() ();
00453 };
00454 
00455 } // namespace gnash
00456 
00457 #endif // GNASH_ACTIONEXEC_H
00458 
00459 // Local Variables:
00460 // mode: C++
00461 // indent-tabs-mode: t
00462 // End:

Generated on Thu Mar 6 18:25:06 2008 for Gnash by  doxygen 1.5.4