Gnash 0.8.9

Global_as.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 
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 
00123     // This is going to be the global Mouse "class"/"function"
00124     Global_as& gl = getGlobal(where);
00125     as_object* obj = createObject(gl);
00126     if (p) p(*obj);
00127     
00128     where.init_member(uri, obj, as_object::DefaultFlags);
00129 
00130     return obj;
00131 }
00132 
00134 //
00136 //
00140 //
00150 inline as_object*
00151 registerBuiltinClass(as_object& where, Global_as::ASFunction ctor,
00152         Global_as::Properties p, Global_as::Properties c, const ObjectURI& uri)
00153 {
00154     Global_as& gl = getGlobal(where);
00155     as_object* proto = createObject(gl);
00156     as_object* cl = gl.createClass(ctor, proto);
00157  
00158     // Attach class properties to class
00159     if (c) c(*cl);
00160 
00161     // Attach prototype properties to prototype
00162     if (p) p(*proto);
00163 
00164     // Register class with specified object.
00165     where.init_member(uri, cl, as_object::DefaultFlags);
00166     return cl;
00167 }
00168 
00170 //
00172 inline DSOEXPORT as_value
00173 invoke(const as_value& method, const as_environment& env, as_object* this_ptr,
00174         fn_call::Args& args, as_object* super = 0,
00175         const movie_definition* callerDef = 0)
00176 {
00177 
00178         as_value val;
00179         fn_call call(this_ptr, env, args);
00180         call.super = super;
00181     call.callerDef = callerDef;
00182 
00183         try {
00184                 if (as_object* func = toObject(method, getVM(env))) {
00185             // Call function.
00186                     val = func->call(call);
00187                 }
00188                 else {
00189             IF_VERBOSE_ASCODING_ERRORS(
00190                 log_aserror("Attempt to call a value which is not "
00191                     "a function (%s)", method);
00192             );
00193             return val;
00194                 }
00195         }
00196         catch (ActionTypeError& e) {
00197                 assert(val.is_undefined());
00198                 IF_VERBOSE_ASCODING_ERRORS(
00199             log_aserror("%s", e.what());
00200                 );
00201         }
00202         return val;
00203 }
00204 
00206 #define VALUE_ARG(z, n, t) BOOST_PP_COMMA_IF(n) t arg##n
00207 
00209 //
00212 //
00215 //
00218 //
00227 #define CALL_METHOD(x, n, t) \
00228 inline as_value \
00229 callMethod(as_object* obj, const ObjectURI& uri BOOST_PP_COMMA_IF(n)\
00230         BOOST_PP_REPEAT(n, VALUE_ARG, const as_value&)) {\
00231     if (!obj) return as_value();\
00232     as_value func;\
00233     if (!obj->get_member(uri, &func)) return as_value();\
00234     fn_call::Args args;\
00235     BOOST_PP_EXPR_IF(n, (args += BOOST_PP_REPEAT(n, VALUE_ARG, ));)\
00236     return invoke(func, as_environment(getVM(*obj)), obj, args);\
00237 }
00238 
00240 #define MAX_ARGS 4
00241 BOOST_PP_REPEAT(BOOST_PP_INC(MAX_ARGS), CALL_METHOD, BOOST_PP_EMPTY)
00242 
00243 
00244 //
00246 inline as_function*
00247 getClassConstructor(const fn_call& fn, const std::string& s)
00248 {
00249     const as_value ctor(findObject(fn.env(), s));
00250     return ctor.to_function();
00251 }
00252 
00253 } // namespace gnash
00254 
00255 #endif