00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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"
00027 #include "smart_ptr.h"
00028
00029 #include <vector>
00030
00031
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,
00049 TRY_CATCH,
00050 TRY_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, 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
00221
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 }
00456
00457 #endif // GNASH_ACTIONEXEC_H
00458
00459
00460
00461
00462