Gnash  0.8.11dev
fn_call.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_FN_CALL_H
20 #define GNASH_FN_CALL_H
21 
22 #include <string>
23 #include <vector>
24 #include <cassert>
25 #include <ostream>
26 #include <algorithm>
27 
28 #include "as_object.h"
29 #include "as_value.h"
30 #include "VM.h"
31 #include "GnashException.h"
32 #include "as_environment.h"
33 
34 
35 // Forward declarations
36 namespace gnash {
37  class movie_definition;
38 }
39 
40 namespace gnash {
41 
43 //
45 //
47 //
50 //
54 template<typename T>
55 class FunctionArgs
56 {
57 public:
58 
59  typedef typename std::vector<T>::size_type size_type;
60  typedef std::vector<T> container_type;
61  typedef T value_type;
62 
64 
66  FunctionArgs(const FunctionArgs& other)
67  :
68  _v(other._v)
69  {}
70 
72  _v.push_back(t);
73  return *this;
74  }
75 
77  _v.push_back(t);
78  return *this;
79  }
80 
82  //
85  void setReachable() const {
86  std::for_each(_v.begin(), _v.end(),
87  std::mem_fun_ref(&as_value::setReachable));
88  }
89 
90  void swap(std::vector<T>& to) {
91  std::swap(_v, to);
92  }
93 
94  size_type size() const {
95  return _v.size();
96  }
97 
98 private:
99  std::vector<T> _v;
100 };
101 
102 
106 class fn_call
107 {
108 public:
109 
111 
113  //
120  fn_call(as_object* this_in, const as_environment& env_in,
121  Args& args, as_object* sup = 0, bool isNew = false)
122  :
123  this_ptr(this_in),
124  super(sup),
125  nargs(args.size()),
126  callerDef(0),
127  _env(env_in),
128  _new(isNew)
129  {
130  args.swap(_args);
131  }
132 
133  fn_call(as_object* this_in, const as_environment& env_in)
134  :
135  this_ptr(this_in),
136  super(0),
137  nargs(0),
138  callerDef(0),
139  _env(env_in),
140  _new(false)
141  {
142  }
143 
145  fn_call(const fn_call& fn)
146  :
147  this_ptr(fn.this_ptr),
148  super(fn.super),
149  nargs(fn.nargs),
150  callerDef(fn.callerDef),
151  _env(fn._env),
152  _args(fn._args),
153  _new(false)
154  {
155  }
156 
160 
162  //
165 
168 
171 
173  VM& getVM() const {
174  return _env.getVM();
175  }
176 
178  bool isInstantiation() const {
179  return _new;
180  }
181 
183  const Args::value_type& arg(unsigned int n) const {
184  assert(n < nargs);
185  return _args[n];
186  }
187 
188  const Args::container_type& getArgs() const {
189  return _args;
190  }
191 
192  void drop_bottom() {
193  assert(!_args.empty());
194  _args.erase(_args.begin());
195  --nargs;
196  }
197 
198  const as_environment& env() const {
199  return _env;
200  }
201 
203  void dump_args(std::ostream& os) const {
204  for (size_t i = 0; i < nargs; ++i) {
205  if (i) os << ", ";
206  os << arg(i);
207  }
208  }
209 
210  void resetArgs() {
211  nargs = 0;
212  _args.clear();
213  }
214 
215  void pushArg(const Args::value_type& arg) {
216  ++nargs;
217  _args.push_back(arg);
218  }
219 
220 private:
221 
224  const as_environment& _env;
225 
227  Args::container_type _args;
228 
229  bool _new;
230 
231 };
232 
233 
235 //
237 template<typename T>
239 {
240  typedef T value_type;
241  value_type* operator()(const as_object* o) const {
242  return dynamic_cast<value_type*>(o->relay());
243  }
244 };
245 
247 //
249 template<typename T = DisplayObject>
251 {
252  typedef T value_type;
253  value_type* operator()(const as_object* o) const {
254  if (!o) return 0;
255  return dynamic_cast<T*>(o->displayObject());
256  }
257 };
258 
260 struct ValidThis
261 {
264  return o;
265  }
266 };
267 
269 //
273 //
278 //
286 template<typename T>
287 typename T::value_type*
288 ensure(const fn_call& fn)
289 {
290  as_object* obj = fn.this_ptr;
291  if (!obj) throw ActionTypeError();
292 
293  typename T::value_type* ret = T()(obj);
294 
295  if (!ret) {
296  std::string target = typeName(ret);
297  std::string source = typeName(obj);
298 
299  std::string msg = "Function requiring " + target + " as 'this' "
300  "called from " + source + " instance.";
301 
302  throw ActionTypeError(msg);
303  }
304  return ret;
305 }
306 
307 inline string_table&
309 {
310  return fn.getVM().getStringTable();
311 }
312 
313 inline movie_root&
314 getRoot(const fn_call& fn)
315 {
316  return fn.getVM().getRoot();
317 }
318 
319 inline int
321 {
322  return fn.getVM().getSWFVersion();
323 }
324 
325 inline VM&
326 getVM(const fn_call& fn)
327 {
328  return fn.getVM();
329 }
330 
331 inline Global_as&
332 getGlobal(const fn_call& fn)
333 {
334  return *fn.getVM().getGlobal();
335 }
336 
337 } // namespace gnash
338 
339 
340 #endif
341 
342 
343 // Local Variables:
344 // mode: C++
345 // indent-tabs-mode: nil
346 // End: