Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef GNASH_FN_CALL_H
00020 #define GNASH_FN_CALL_H
00021
00022 #include "as_environment.h"
00023 #include "as_object.h"
00024 #include "as_value.h"
00025 #include "VM.h"
00026 #include "GnashException.h"
00027
00028 #include <string>
00029 #include <vector>
00030 #include <cassert>
00031 #include <ostream>
00032 #include <sstream>
00033 #include <algorithm>
00034
00035
00036 namespace gnash {
00037 class as_environment;
00038 class as_function;
00039 class movie_definition;
00040 }
00041
00042 namespace gnash {
00043
00045
00047
00049
00052
00056 template<typename T>
00057 class FunctionArgs
00058 {
00059 public:
00060
00061 typedef typename std::vector<T>::size_type size_type;
00062 typedef std::vector<T> container_type;
00063 typedef T value_type;
00064
00065 FunctionArgs() {}
00066
00068 FunctionArgs(const FunctionArgs& other)
00069 :
00070 _v(other._v)
00071 {}
00072
00073 FunctionArgs& operator+=(const T& t) {
00074 _v.push_back(t);
00075 return *this;
00076 }
00077
00078 FunctionArgs& operator,(const T& t) {
00079 _v.push_back(t);
00080 return *this;
00081 }
00082
00084
00087 void setReachable() const {
00088 std::for_each(_v.begin(), _v.end(),
00089 std::mem_fun_ref(&as_value::setReachable));
00090 }
00091
00092 void swap(std::vector<T>& to) {
00093 std::swap(_v, to);
00094 }
00095
00096 size_type size() const {
00097 return _v.size();
00098 }
00099
00100 private:
00101 std::vector<T> _v;
00102 };
00103
00104
00108 class fn_call
00109 {
00110 public:
00111
00112 typedef FunctionArgs<as_value> Args;
00113
00115
00122 fn_call(as_object* this_in, const as_environment& env_in,
00123 Args& args, as_object* sup = 0, bool isNew = false)
00124 :
00125 this_ptr(this_in),
00126 super(sup),
00127 nargs(args.size()),
00128 callerDef(0),
00129 _env(env_in),
00130 _new(isNew)
00131 {
00132 args.swap(_args);
00133 }
00134
00135 fn_call(as_object* this_in, const as_environment& env_in)
00136 :
00137 this_ptr(this_in),
00138 super(0),
00139 nargs(0),
00140 callerDef(0),
00141 _env(env_in),
00142 _new(false)
00143 {
00144 }
00145
00147 fn_call(const fn_call& fn)
00148 :
00149 this_ptr(fn.this_ptr),
00150 super(fn.super),
00151 nargs(fn.nargs),
00152 callerDef(fn.callerDef),
00153 _env(fn._env),
00154 _args(fn._args),
00155 _new(false)
00156 {
00157 }
00158
00161 as_object* this_ptr;
00162
00164
00166 as_object* super;
00167
00169 Args::size_type nargs;
00170
00172 const movie_definition* callerDef;
00173
00175 VM& getVM() const {
00176 return _env.getVM();
00177 }
00178
00180 bool isInstantiation() const {
00181 return _new;
00182 }
00183
00185 const Args::value_type& arg(unsigned int n) const {
00186 assert(n < nargs);
00187 return _args[n];
00188 }
00189
00190 const Args::container_type& getArgs() const {
00191 return _args;
00192 }
00193
00194 void drop_bottom() {
00195 assert(!_args.empty());
00196 _args.erase(_args.begin());
00197 --nargs;
00198 }
00199
00200 const as_environment& env() const {
00201 return _env;
00202 }
00203
00205 void dump_args(std::ostream& os) const {
00206 for (size_t i = 0; i < nargs; ++i) {
00207 if ( i ) os << ", ";
00208 os << arg(i).toDebugString();
00209 }
00210 }
00211
00212 void resetArgs() {
00213 nargs = 0;
00214 _args.clear();
00215 }
00216
00217 void pushArg(const Args::value_type& arg) {
00218 ++nargs;
00219 _args.push_back(arg);
00220 }
00221
00222 private:
00223
00226 const as_environment& _env;
00227
00229 Args::container_type _args;
00230
00231 bool _new;
00232
00233 };
00234
00235
00237
00239 template<typename T>
00240 struct ThisIsNative
00241 {
00242 typedef T value_type;
00243 value_type* operator()(as_object* o) const {
00244 return dynamic_cast<value_type*>(o->relay());
00245 }
00246 };
00247
00249
00251 template<typename T = DisplayObject>
00252 struct IsDisplayObject
00253 {
00254 typedef T value_type;
00255 value_type* operator()(as_object* o) const {
00256 if (!o) return 0;
00257 return dynamic_cast<T*>(o->displayObject());
00258 }
00259 };
00260
00262 struct ValidThis
00263 {
00264 typedef as_object value_type;
00265 value_type* operator()(as_object* o) const {
00266 return o;
00267 }
00268 };
00269
00271
00275
00280
00288 template<typename T>
00289 typename T::value_type*
00290 ensure(const fn_call& fn)
00291 {
00292 as_object* obj = fn.this_ptr;
00293 if (!obj) throw ActionTypeError();
00294
00295 typename T::value_type* ret = T()(obj);
00296
00297 if (!ret) {
00298 std::string target = typeName(ret);
00299 std::string source = typeName(obj);
00300
00301 std::string msg = "Function requiring " + target + " as 'this' "
00302 "called from " + source + " instance.";
00303
00304 throw ActionTypeError(msg);
00305 }
00306 return ret;
00307 }
00308
00309 inline string_table&
00310 getStringTable(const fn_call& fn)
00311 {
00312 return fn.getVM().getStringTable();
00313 }
00314
00315 inline movie_root&
00316 getRoot(const fn_call& fn)
00317 {
00318 return fn.getVM().getRoot();
00319 }
00320
00321 inline int
00322 getSWFVersion(const fn_call& fn)
00323 {
00324 return fn.getVM().getSWFVersion();
00325 }
00326
00327 inline VM&
00328 getVM(const fn_call& fn)
00329 {
00330 return fn.getVM();
00331 }
00332
00333 inline Global_as&
00334 getGlobal(const fn_call& fn)
00335 {
00336 return *fn.getVM().getGlobal();
00337 }
00338
00339 }
00340
00341
00342 #endif
00343
00344
00345
00346
00347
00348