Gnash  0.8.10
ActionExec.h
Go to the documentation of this file.
00001 // 
00002 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
00003 //   Free Software Foundation, Inc
00004 // 
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 3 of the License, or
00008 // (at your option) any later version.
00009 // 
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 #ifndef GNASH_ACTIONEXEC_H
00020 #define GNASH_ACTIONEXEC_H
00021 
00022 #include <string>
00023 #include <list>
00024 #include <vector>
00025 #include <boost/noncopyable.hpp>
00026 
00027 #include "as_environment.h" 
00028 #include "SWF.h"
00029 #include "action_buffer.h"
00030 
00031 // Forward declarations
00032 namespace gnash {
00033         class as_value;
00034         class Function;
00035         class ActionExec;
00036 }
00037 
00038 namespace gnash {
00039 
00040 class TryBlock
00041 {
00042 public:
00043         friend class ActionExec;
00044 
00045         enum tryState
00046         {
00047                 TRY_TRY, // In a try block.
00048                 TRY_CATCH, // In a catch block.
00049                 TRY_FINALLY, // In a finally block.
00050                 TRY_END // Finished with finally
00051         };
00052 
00053     TryBlock(size_t cur_off, size_t try_size, size_t catch_size,
00054                 size_t finally_size, std::string catchName)
00055                 :
00056                 _catchOffset(cur_off + try_size),
00057                 _finallyOffset(cur_off + try_size + catch_size),
00058                 _afterTriedOffset(cur_off + try_size + catch_size + finally_size),
00059                 _hasName(true),
00060                 _name(catchName),
00061                 _registerIndex(0),
00062                 _tryState(TryBlock::TRY_TRY),
00063                 _lastThrow()
00064         {}
00065 
00066         TryBlock(size_t cur_off, size_t try_size, size_t catch_size,
00067                 size_t finally_size, boost::uint8_t register_index)
00068                 :
00069                 _catchOffset(cur_off + try_size),
00070                 _finallyOffset(cur_off + try_size + catch_size),
00071                 _afterTriedOffset(cur_off + try_size + catch_size + finally_size),
00072                 _hasName(false),
00073                 _name(),
00074                 _registerIndex(register_index),
00075                 _tryState(TryBlock::TRY_TRY),
00076                 _lastThrow()
00077         {}
00078 
00079 private:
00080         size_t _catchOffset;
00081         size_t _finallyOffset;
00082         size_t _afterTriedOffset;
00083         size_t _savedEndOffset;
00084         bool _hasName;
00085         std::string _name;
00086         unsigned int _registerIndex;
00087         tryState _tryState;
00088         as_value _lastThrow;
00089 };
00090 
00091 class With
00092 {
00093 public: 
00094 
00095         With(as_object* obj, size_t end)
00096                 :
00097                 _object(obj),
00098                 _block_end_pc(end)
00099         {
00100         }
00101 
00102         size_t end_pc() const {
00103                 return _block_end_pc;
00104         }
00105 
00106         as_object* object() const {
00107                 return _object;
00108         }
00109 
00110 private:
00111         as_object* _object;
00112         size_t _block_end_pc;
00113 };
00114 
00116 class ActionExec : boost::noncopyable
00117 {
00118 
00119     typedef as_environment::ScopeStack ScopeStack;
00120 
00121 public:
00122 
00124         //
00130         ActionExec(const action_buffer& abuf, as_environment& newEnv,
00131             bool abortOnUnloaded = true);
00132 
00134         //
00139         ActionExec(const Function& func, as_environment& newEnv,
00140             as_value* nRetVal, as_object* this_ptr);
00141 
00143         void pushTryBlock(TryBlock t);
00144 
00146         void pushReturn(const as_value& t);
00147 
00149         //
00151         const action_buffer& code;
00152 
00154         as_environment& env;
00155 
00157         as_value* retval;
00158 
00160         bool isFunction() const { return _func != 0; }
00161 
00163         as_object* getThisPointer();
00164 
00166         const ScopeStack& getScopeStack() const {
00167                 return _scopeStack;
00168         }
00169 
00171         //
00174         bool pushWith(const With& entry);
00175 
00177         //
00179         void skip_actions(size_t offset);
00180 
00182         //
00184         bool delVariable(const std::string& name);
00185 
00187         //
00189         void setVariable(const std::string& name, const as_value& val);
00190 
00192     //
00194         //
00197         void setLocalVariable(const std::string& name, const as_value& val);
00198 
00200         //
00206         as_value getVariable(const std::string& name, as_object** target = 0);
00207 
00209         //
00218         as_object* getTarget();
00219 
00221         void operator()();
00222 
00223     // TODO: cut down these accessors.
00224     bool atActionTag(SWF::ActionType t) { return code[pc] == t; }
00225         
00226         size_t getCurrentPC() const { return pc; }
00227         
00228         void skipRemainingBuffer() { next_pc = stop_pc; }
00229         
00230         void adjustNextPC(int offset);
00231         
00232         size_t getNextPC() const { return next_pc; }
00233         
00234         void setNextPC(size_t pc) { next_pc = pc; }
00235         
00236         size_t getStopPC() const { return stop_pc; }
00237         
00238 private: 
00239 
00243         //
00253         void dumpActions(size_t start, size_t end, std::ostream& os);
00254 
00256     //
00265     //
00268     bool processExceptions(TryBlock& t);
00269 
00272         //
00285         void cleanupAfterRun();
00286 
00288         std::vector<With> _withStack;
00289 
00291         ScopeStack _scopeStack;
00292 
00301         const Function* _func;
00302 
00304         as_object* _this_ptr;
00305 
00307         size_t _initialStackSize;
00308 
00309         DisplayObject* _originalTarget;
00310 
00311         int _origExecSWFVersion;
00312 
00313         std::list<TryBlock> _tryList;
00314 
00315         bool _returning;
00316 
00317         bool _abortOnUnload;
00318 
00320         size_t pc;
00321 
00323         size_t next_pc;
00324 
00327         size_t stop_pc;
00328 
00329 };
00330 
00331 } // namespace gnash
00332 
00333 #endif // GNASH_ACTIONEXEC_H
00334 
00335 // Local Variables:
00336 // mode: C++
00337 // indent-tabs-mode: t
00338 // End: