Gnash 0.8.9
|
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