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