Gnash
0.8.10
|
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: