Merge branch 'master' of git.sv.gnu.org:/srv/git/gnash
[gnash.git] / libcore / asobj / Global_as.h
blobc237f8a09cf0d593215048103197a19371631a12
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 // Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #ifndef GNASH_GLOBAL_H
21 #define GNASH_GLOBAL_H
23 #include <string>
24 #include <boost/preprocessor/arithmetic/inc.hpp>
25 #include <boost/preprocessor/repetition/enum_params.hpp>
26 #include <boost/preprocessor/repetition/repeat.hpp>
27 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
28 #include <boost/preprocessor/seq/for_each.hpp>
29 #include <boost/scoped_ptr.hpp>
31 #include "as_object.h"
32 #include "fn_call.h"
33 #include "log.h"
34 #include "ClassHierarchy.h"
36 // Forward declarations
37 namespace gnash {
38 class builtin_function;
39 class as_value;
40 class VM;
41 class Extension;
44 namespace gnash {
46 /// The Global object ultimately contains all objects in an ActionScript run
48 /// An ActionScript run is a single version (AS1/2 or AS3) and includes all
49 /// resources parsed from the SWF, created dynamically, loaded, or imported
50 /// that are available to ActionScript code.
52 /// Each VM (VM for AS1/2, Machine for AS3) has different resources in its
53 /// Global object. The two objects should be entirely separate.
54 class Global_as : public as_object
56 public:
58 typedef as_value(*ASFunction)(const fn_call& fn);
59 typedef void(*Properties)(as_object&);
61 explicit Global_as(VM& vm);
62 virtual ~Global_as();
64 void registerClasses();
66 as_object* createArray();
68 VM& getVM() const {
69 return vm();
72 /// Create an ActionScript function
73 builtin_function* createFunction(Global_as::ASFunction function);
75 /// Create an ActionScript class
77 /// An AS2 class is generally a function (the constructor) with a
78 /// prototype.
79 as_object* createClass(Global_as::ASFunction ctor,
80 as_object* prototype);
82 void makeObject(as_object& o) const;
84 protected:
86 virtual void markReachableResources() const;
88 private:
90 void loadExtensions();
91 boost::scoped_ptr<Extension> _et;
93 ClassHierarchy _classes;
95 as_object* _objectProto;
99 as_object* createObject(const Global_as& gl);
102 /// Register a built-in object
104 /// This is used for simple objects that are part of the player API.
106 /// In the reference player these objects are always constructed in
107 /// ActionScript, though their functions may be native.
109 /// They include (AS2) Mouse, Selection and Stage, and (AS3) all constant
110 /// enumeration objects.
112 /// @param p a pointer to a function that will attach properties to the
113 /// object
114 /// @param where the object to which the created object will be attached
115 /// @param uri an ObjectURI describing the name and namespace of the
116 /// created object.
117 /// @return the built-in object with properties attached.
118 inline as_object*
119 registerBuiltinObject(as_object& where, Global_as::Properties p,
120 const ObjectURI& uri)
123 // This is going to be the global Mouse "class"/"function"
124 Global_as& gl = getGlobal(where);
125 as_object* obj = createObject(gl);
126 if (p) p(*obj);
128 where.init_member(uri, obj, as_object::DefaultFlags);
130 return obj;
133 /// Register a built-in class
135 /// This is used for classes that are part of the player API.
137 /// In the reference player these classes are always constructed in
138 /// ActionScript, though their functions may be native, and the constructor
139 /// may also call native functions.
141 /// @param c a pointer to a function that will attach properties to the
142 /// class itself. These are known as static properties.
143 /// @param p a pointer to a function that will attach properties to the
144 /// class prototype. These are instance properties.
145 /// @param ctor the constructor function for the new class.
146 /// @param where the object to which the created object will be attached
147 /// @param uri an ObjectURI describing the name and namespace of the
148 /// created object.
149 /// @return the built-in class with prototype and properties attached.
150 inline as_object*
151 registerBuiltinClass(as_object& where, Global_as::ASFunction ctor,
152 Global_as::Properties p, Global_as::Properties c, const ObjectURI& uri)
154 Global_as& gl = getGlobal(where);
155 as_object* proto = createObject(gl);
156 as_object* cl = gl.createClass(ctor, proto);
158 // Attach class properties to class
159 if (c) c(*cl);
161 // Attach prototype properties to prototype
162 if (p) p(*proto);
164 // Register class with specified object.
165 where.init_member(uri, cl, as_object::DefaultFlags);
166 return cl;
169 /// Call an as_value on an as_object.
171 /// The call will fail harmlessly if the as_value is not callable.
172 inline DSOEXPORT as_value
173 invoke(const as_value& method, const as_environment& env, as_object* this_ptr,
174 fn_call::Args& args, as_object* super = 0,
175 const movie_definition* callerDef = 0)
178 as_value val;
179 fn_call call(this_ptr, env, args);
180 call.super = super;
181 call.callerDef = callerDef;
183 try {
184 if (as_object* func = toObject(method, getVM(env))) {
185 // Call function.
186 val = func->call(call);
188 else {
189 IF_VERBOSE_ASCODING_ERRORS(
190 log_aserror("Attempt to call a value which is not "
191 "a function (%s)", method);
193 return val;
196 catch (ActionTypeError& e) {
197 assert(val.is_undefined());
198 IF_VERBOSE_ASCODING_ERRORS(
199 log_aserror("%s", e.what());
202 return val;
205 /// Helper macro for callMethod arguments.
206 #define VALUE_ARG(z, n, t) BOOST_PP_COMMA_IF(n) t arg##n
208 /// Call a member function of this object in an AS-compatible way
210 /// This is a macro to cope with a varying number of arguments. The function
211 /// signature is as follows:
213 /// as_value callMethod(as_object* obj, const ObjectURI& uri,
214 /// const as_value& arg1, ..., const as_value& argN);
216 /// If the member function exists and is a function, invoke() is called on
217 /// the member with the object as the this pointer.
219 /// @param obj The object to call the method on. This may be null, in
220 /// which case the call is a no-op. This is because calling
221 /// methods on null or non-objects in AS is harmless.
222 /// @param name The name of the method.
224 /// @param arg0..argN The arguments to pass
226 /// @return The return value of the call (possibly undefined).
227 #define CALL_METHOD(x, n, t) \
228 inline as_value \
229 callMethod(as_object* obj, const ObjectURI& uri BOOST_PP_COMMA_IF(n)\
230 BOOST_PP_REPEAT(n, VALUE_ARG, const as_value&)) {\
231 if (!obj) return as_value();\
232 as_value func;\
233 if (!obj->get_member(uri, &func)) return as_value();\
234 fn_call::Args args;\
235 BOOST_PP_EXPR_IF(n, (args += BOOST_PP_REPEAT(n, VALUE_ARG, ));)\
236 return invoke(func, as_environment(getVM(*obj)), obj, args);\
239 /// The maximum number of as_value arguments allowed in callMethod functions.
240 #define MAX_ARGS 4
241 BOOST_PP_REPEAT(BOOST_PP_INC(MAX_ARGS), CALL_METHOD, )
243 /// Convenience function for finding a class constructor.
245 /// Only currently useful in AS2.
246 inline as_function*
247 getClassConstructor(const fn_call& fn, const std::string& s)
249 const as_value ctor(findObject(fn.env(), s));
250 return ctor.to_function();
253 } // namespace gnash
255 #endif