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