Gnash  0.8.10
Global_as.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 
00020 #ifndef GNASH_GLOBAL_H
00021 #define GNASH_GLOBAL_H
00022 
00023 #include <string>
00024 #include <boost/preprocessor/arithmetic/inc.hpp>
00025 #include <boost/preprocessor/repetition/enum_params.hpp>
00026 #include <boost/preprocessor/repetition/repeat.hpp>
00027 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
00028 #include <boost/preprocessor/seq/for_each.hpp>
00029 #include <boost/preprocessor/facilities/empty.hpp>
00030 #include <boost/scoped_ptr.hpp>
00031 
00032 #include "as_object.h" 
00033 #include "fn_call.h"
00034 #include "log.h"
00035 #include "ClassHierarchy.h"
00036 
00037 // Forward declarations
00038 namespace gnash {
00039     class as_value;
00040     class VM;
00041     class Extension;
00042 }
00043 
00044 namespace gnash {
00045 
00047 //
00051 //
00054 class Global_as : public as_object
00055 {
00056 public:
00057 
00058     typedef as_value(*ASFunction)(const fn_call& fn);
00059     typedef void(*Properties)(as_object&);
00060 
00061         explicit Global_as(VM& vm);
00062         virtual ~Global_as();
00063     
00064     void registerClasses();
00065 
00066     as_object* createArray();
00067 
00068     VM& getVM() const {
00069         return vm();
00070     }
00071     
00073     as_function* createFunction(Global_as::ASFunction function);
00074 
00076     //
00079     as_object* createClass(Global_as::ASFunction ctor,
00080             as_object* prototype);
00081 
00082     void makeObject(as_object& o) const;
00083 
00084 protected:
00085     
00086     virtual void markReachableResources() const;
00087 
00088 private:
00089 
00090     void loadExtensions();
00091     boost::scoped_ptr<Extension> _et;
00092 
00093     ClassHierarchy _classes;
00094     
00095     as_object* _objectProto;
00096 
00097 };
00098 
00099 as_object* createObject(const Global_as& gl);
00100     
00101 
00103 //
00105 //
00108 //
00111 //
00118 inline as_object*
00119 registerBuiltinObject(as_object& where, Global_as::Properties p,
00120         const ObjectURI& uri)
00121 {
00122     Global_as& gl = getGlobal(where);
00123     as_object* obj = createObject(gl);
00124     if (p) p(*obj);
00125     
00126     where.init_member(uri, obj, as_object::DefaultFlags);
00127 
00128     return obj;
00129 }
00130 
00132 //
00134 //
00138 //
00148 inline as_object*
00149 registerBuiltinClass(as_object& where, Global_as::ASFunction ctor,
00150         Global_as::Properties p, Global_as::Properties c, const ObjectURI& uri)
00151 {
00152     Global_as& gl = getGlobal(where);
00153     as_object* proto = createObject(gl);
00154     as_object* cl = gl.createClass(ctor, proto);
00155  
00156     // Attach class properties to class
00157     if (c) c(*cl);
00158 
00159     // Attach prototype properties to prototype
00160     if (p) p(*proto);
00161 
00162     // Register class with specified object.
00163     where.init_member(uri, cl, as_object::DefaultFlags);
00164     return cl;
00165 }
00166 
00168 //
00170 inline DSOEXPORT as_value
00171 invoke(const as_value& method, const as_environment& env, as_object* this_ptr,
00172         fn_call::Args& args, as_object* super = 0,
00173         const movie_definition* callerDef = 0)
00174 {
00175 
00176         as_value val;
00177         fn_call call(this_ptr, env, args);
00178         call.super = super;
00179     call.callerDef = callerDef;
00180 
00181         try {
00182                 if (as_object* func = toObject(method, getVM(env))) {
00183             // Call function.
00184                     val = func->call(call);
00185                 }
00186                 else {
00187             IF_VERBOSE_ASCODING_ERRORS(
00188                 log_aserror("Attempt to call a value which is not "
00189                     "a function (%s)", method);
00190             );
00191             return val;
00192                 }
00193         }
00194         catch (ActionTypeError& e) {
00195                 assert(val.is_undefined());
00196                 IF_VERBOSE_ASCODING_ERRORS(
00197             log_aserror("%s", e.what());
00198                 );
00199         }
00200         return val;
00201 }
00202 
00204 #define FUNC_PARAM(z, n, t) BOOST_PP_COMMA_IF(n) t arg##n
00205 #define VALUE_ARG(z, n, t) BOOST_PP_COMMA_IF(n) arg##n
00206 
00208 //
00211 //
00214 //
00217 //
00226 #define CALL_METHOD(x, n, t) \
00227 inline as_value \
00228 callMethod(as_object* obj, const ObjectURI& uri BOOST_PP_COMMA_IF(n)\
00229         BOOST_PP_REPEAT(n, FUNC_PARAM, const as_value&)) {\
00230     if (!obj) return as_value();\
00231     as_value func;\
00232     if (!obj->get_member(uri, &func)) return as_value();\
00233     fn_call::Args args;\
00234     BOOST_PP_EXPR_IF(n, (args += BOOST_PP_REPEAT(n, VALUE_ARG, BOOST_PP_EMPTY));)\
00235     return invoke(func, as_environment(getVM(*obj)), obj, args);\
00236 }
00237 
00239 #define MAX_ARGS 4
00240 BOOST_PP_REPEAT(BOOST_PP_INC(MAX_ARGS), CALL_METHOD, BOOST_PP_EMPTY)
00241 
00242 #undef VALUE_ARG
00243 #undef FUNC_PARAM
00244 #undef MAX_ARGS
00245 #undef CALL_METHOD
00246 
00248 //
00250 inline as_function*
00251 getClassConstructor(const fn_call& fn, const std::string& s)
00252 {
00253     const as_value ctor(findObject(fn.env(), s));
00254     return ctor.to_function();
00255 }
00256 
00257 inline as_value
00258 emptyFunction(const fn_call&)
00259 {
00260     return as_value();
00261 }
00262 
00263 } // namespace gnash
00264 
00265 #endif