Gnash  0.8.10
fn_call.h
Go to the documentation of this file.
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: