Gnash 0.8.9

fn_call.h

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