Gnash  0.8.11dev
ActionExec.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 #ifndef GNASH_ACTIONEXEC_H
20 #define GNASH_ACTIONEXEC_H
21 
22 #include <string>
23 #include <list>
24 #include <vector>
25 #include <boost/noncopyable.hpp>
26 
27 #include "as_environment.h"
28 #include "SWF.h"
29 #include "action_buffer.h"
30 
31 // Forward declarations
32 namespace gnash {
33  class as_value;
34  class Function;
35  class ActionExec;
36 }
37 
38 namespace gnash {
39 
40 class TryBlock
41 {
42 public:
43  friend class ActionExec;
44 
45  enum tryState
46  {
47  TRY_TRY, // In a try block.
48  TRY_CATCH, // In a catch block.
49  TRY_FINALLY, // In a finally block.
50  TRY_END // Finished with finally
51  };
52 
53  TryBlock(size_t cur_off, size_t try_size, size_t catch_size,
54  size_t finally_size, std::string catchName)
55  :
56  _catchOffset(cur_off + try_size),
57  _finallyOffset(cur_off + try_size + catch_size),
58  _afterTriedOffset(cur_off + try_size + catch_size + finally_size),
59  _hasName(true),
60  _name(catchName),
61  _registerIndex(0),
62  _tryState(TryBlock::TRY_TRY),
63  _lastThrow()
64  {}
65 
66  TryBlock(size_t cur_off, size_t try_size, size_t catch_size,
67  size_t finally_size, boost::uint8_t register_index)
68  :
69  _catchOffset(cur_off + try_size),
70  _finallyOffset(cur_off + try_size + catch_size),
71  _afterTriedOffset(cur_off + try_size + catch_size + finally_size),
72  _hasName(false),
73  _name(),
74  _registerIndex(register_index),
75  _tryState(TryBlock::TRY_TRY),
76  _lastThrow()
77  {}
78 
79 private:
80  size_t _catchOffset;
81  size_t _finallyOffset;
82  size_t _afterTriedOffset;
83  size_t _savedEndOffset;
84  bool _hasName;
85  std::string _name;
86  unsigned int _registerIndex;
87  tryState _tryState;
88  as_value _lastThrow;
89 };
90 
91 class With
92 {
93 public:
94 
95  With(as_object* obj, size_t end)
96  :
97  _object(obj),
98  _block_end_pc(end)
99  {
100  }
101 
102  size_t end_pc() const {
103  return _block_end_pc;
104  }
105 
106  as_object* object() const {
107  return _object;
108  }
109 
110 private:
111  as_object* _object;
112  size_t _block_end_pc;
113 };
114 
116 class ActionExec : boost::noncopyable
117 {
118 
119  typedef as_environment::ScopeStack ScopeStack;
120 
121 public:
122 
124  //
130  ActionExec(const action_buffer& abuf, as_environment& newEnv,
131  bool abortOnUnloaded = true);
132 
134  //
139  ActionExec(const Function& func, as_environment& newEnv,
140  as_value* nRetVal, as_object* this_ptr);
141 
143  void pushTryBlock(TryBlock t);
144 
146  void pushReturn(const as_value& t);
147 
149  //
152 
155 
158 
160  bool isFunction() const { return _func != 0; }
161 
164 
166  const ScopeStack& getScopeStack() const {
167  return _scopeStack;
168  }
169 
171  //
174  bool pushWith(const With& entry);
175 
177  //
179  void skip_actions(size_t offset);
180 
182  //
184  bool delVariable(const std::string& name);
185 
187  //
189  void setVariable(const std::string& name, const as_value& val);
190 
192  //
194  //
197  void setLocalVariable(const std::string& name, const as_value& val);
198 
200  //
206  as_value getVariable(const std::string& name, as_object** target = 0);
207 
209  //
218  as_object* getTarget();
219 
221  void operator()();
222 
223  // TODO: cut down these accessors.
224  bool atActionTag(SWF::ActionType t) { return code[pc] == t; }
225 
226  size_t getCurrentPC() const { return pc; }
227 
228  void skipRemainingBuffer() { next_pc = stop_pc; }
229 
230  void adjustNextPC(int offset);
231 
232  size_t getNextPC() const { return next_pc; }
233 
234  void setNextPC(size_t pc) { next_pc = pc; }
235 
236  size_t getStopPC() const { return stop_pc; }
237 
238 private:
239 
243  //
253  void dumpActions(size_t start, size_t end, std::ostream& os);
254 
256  //
265  //
268  bool processExceptions(TryBlock& t);
269 
272  //
285  void cleanupAfterRun();
286 
288  std::vector<With> _withStack;
289 
291  ScopeStack _scopeStack;
292 
301  const Function* _func;
302 
304  as_object* _this_ptr;
305 
307  size_t _initialStackSize;
308 
309  DisplayObject* _originalTarget;
310 
311  int _origExecSWFVersion;
312 
313  std::list<TryBlock> _tryList;
314 
315  bool _returning;
316 
317  bool _abortOnUnload;
318 
320  size_t pc;
321 
323  size_t next_pc;
324 
327  size_t stop_pc;
328 
329 };
330 
331 } // namespace gnash
332 
333 #endif // GNASH_ACTIONEXEC_H
334 
335 // Local Variables:
336 // mode: C++
337 // indent-tabs-mode: t
338 // End: