Gnash 0.8.9
|
00001 // 00002 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 00003 // 2011 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_FN_CALL_H 00020 #define GNASH_FN_CALL_H 00021 00022 #include <string> 00023 #include <vector> 00024 #include <cassert> 00025 #include <ostream> 00026 #include <sstream> 00027 #include <algorithm> 00028 00029 #include "as_object.h" 00030 #include "as_value.h" 00031 #include "VM.h" 00032 #include "GnashException.h" 00033 #include "as_environment.h" 00034 00035 00036 // Forward declarations 00037 namespace gnash { 00038 class movie_definition; 00039 } 00040 00041 namespace gnash { 00042 00044 // 00046 // 00048 // 00051 // 00055 template<typename T> 00056 class FunctionArgs 00057 { 00058 public: 00059 00060 typedef typename std::vector<T>::size_type size_type; 00061 typedef std::vector<T> container_type; 00062 typedef T value_type; 00063 00064 FunctionArgs() {} 00065 00067 FunctionArgs(const FunctionArgs& other) 00068 : 00069 _v(other._v) 00070 {} 00071 00072 FunctionArgs& operator+=(const T& t) { 00073 _v.push_back(t); 00074 return *this; 00075 } 00076 00077 FunctionArgs& operator,(const T& t) { 00078 _v.push_back(t); 00079 return *this; 00080 } 00081 00083 // 00086 void setReachable() const { 00087 std::for_each(_v.begin(), _v.end(), 00088 std::mem_fun_ref(&as_value::setReachable)); 00089 } 00090 00091 void swap(std::vector<T>& to) { 00092 std::swap(_v, to); 00093 } 00094 00095 size_type size() const { 00096 return _v.size(); 00097 } 00098 00099 private: 00100 std::vector<T> _v; 00101 }; 00102 00103 00107 class fn_call 00108 { 00109 public: 00110 00111 typedef FunctionArgs<as_value> Args; 00112 00114 // 00121 fn_call(as_object* this_in, const as_environment& env_in, 00122 Args& args, as_object* sup = 0, bool isNew = false) 00123 : 00124 this_ptr(this_in), 00125 super(sup), 00126 nargs(args.size()), 00127 callerDef(0), 00128 _env(env_in), 00129 _new(isNew) 00130 { 00131 args.swap(_args); 00132 } 00133 00134 fn_call(as_object* this_in, const as_environment& env_in) 00135 : 00136 this_ptr(this_in), 00137 super(0), 00138 nargs(0), 00139 callerDef(0), 00140 _env(env_in), 00141 _new(false) 00142 { 00143 } 00144 00146 fn_call(const fn_call& fn) 00147 : 00148 this_ptr(fn.this_ptr), 00149 super(fn.super), 00150 nargs(fn.nargs), 00151 callerDef(fn.callerDef), 00152 _env(fn._env), 00153 _args(fn._args), 00154 _new(false) 00155 { 00156 } 00157 00160 as_object* this_ptr; 00161 00163 // 00165 as_object* super; 00166 00168 Args::size_type nargs; 00169 00171 const movie_definition* callerDef; 00172 00174 VM& getVM() const { 00175 return _env.getVM(); 00176 } 00177 00179 bool isInstantiation() const { 00180 return _new; 00181 } 00182 00184 const Args::value_type& arg(unsigned int n) const { 00185 assert(n < nargs); 00186 return _args[n]; 00187 } 00188 00189 const Args::container_type& getArgs() const { 00190 return _args; 00191 } 00192 00193 void drop_bottom() { 00194 assert(!_args.empty()); 00195 _args.erase(_args.begin()); 00196 --nargs; 00197 } 00198 00199 const as_environment& env() const { 00200 return _env; 00201 } 00202 00204 void dump_args(std::ostream& os) const { 00205 for (size_t i = 0; i < nargs; ++i) { 00206 if (i) os << ", "; 00207 os << arg(i); 00208 } 00209 } 00210 00211 void resetArgs() { 00212 nargs = 0; 00213 _args.clear(); 00214 } 00215 00216 void pushArg(const Args::value_type& arg) { 00217 ++nargs; 00218 _args.push_back(arg); 00219 } 00220 00221 private: 00222 00225 const as_environment& _env; 00226 00228 Args::container_type _args; 00229 00230 bool _new; 00231 00232 }; 00233 00234 00236 // 00238 template<typename T> 00239 struct ThisIsNative 00240 { 00241 typedef T value_type; 00242 value_type* operator()(const as_object* o) const { 00243 return dynamic_cast<value_type*>(o->relay()); 00244 } 00245 }; 00246 00248 // 00250 template<typename T = DisplayObject> 00251 struct IsDisplayObject 00252 { 00253 typedef T value_type; 00254 value_type* operator()(const as_object* o) const { 00255 if (!o) return 0; 00256 return dynamic_cast<T*>(o->displayObject()); 00257 } 00258 }; 00259 00261 struct ValidThis 00262 { 00263 typedef as_object value_type; 00264 value_type* operator()(as_object* o) const { 00265 return o; 00266 } 00267 }; 00268 00270 // 00274 // 00279 // 00287 template<typename T> 00288 typename T::value_type* 00289 ensure(const fn_call& fn) 00290 { 00291 as_object* obj = fn.this_ptr; 00292 if (!obj) throw ActionTypeError(); 00293 00294 typename T::value_type* ret = T()(obj); 00295 00296 if (!ret) { 00297 std::string target = typeName(ret); 00298 std::string source = typeName(obj); 00299 00300 std::string msg = "Function requiring " + target + " as 'this' " 00301 "called from " + source + " instance."; 00302 00303 throw ActionTypeError(msg); 00304 } 00305 return ret; 00306 } 00307 00308 inline string_table& 00309 getStringTable(const fn_call& fn) 00310 { 00311 return fn.getVM().getStringTable(); 00312 } 00313 00314 inline movie_root& 00315 getRoot(const fn_call& fn) 00316 { 00317 return fn.getVM().getRoot(); 00318 } 00319 00320 inline int 00321 getSWFVersion(const fn_call& fn) 00322 { 00323 return fn.getVM().getSWFVersion(); 00324 } 00325 00326 inline VM& 00327 getVM(const fn_call& fn) 00328 { 00329 return fn.getVM(); 00330 } 00331 00332 inline Global_as& 00333 getGlobal(const fn_call& fn) 00334 { 00335 return *fn.getVM().getGlobal(); 00336 } 00337 00338 } // namespace gnash 00339 00340 00341 #endif 00342 00343 00344 // Local Variables: 00345 // mode: C++ 00346 // indent-tabs-mode: nil 00347 // End: