2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
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.
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
19 #ifndef GNASH_FN_CALL_H
20 #define GNASH_FN_CALL_H
29 #include "as_object.h"
32 #include "GnashException.h"
33 #include "as_environment.h"
36 // Forward declarations
38 class movie_definition
;
43 /// A class to contain transferable arguments for a fn_call.
45 /// The operators += and , are implemented for intuitive syntax:
47 /// FunctionArgs<as_value> args; args += 0.0, "string", NaN.
49 /// This may have unexpected side effects if it is used in unexpected ways,
50 /// so stick to using such lists, or use operator += repeatedly.
52 /// The arguments can be moved to another container, and this happens when
53 /// the FunctionArgs object is passed to fn_call. It will still be valid
54 /// afterwards, but will contain no arguments.
60 typedef typename
std::vector
<T
>::size_type size_type
;
61 typedef std::vector
<T
> container_type
;
66 /// The copy constructor copies all the arguments.
67 FunctionArgs(const FunctionArgs
& other
)
72 FunctionArgs
& operator+=(const T
& t
) {
77 FunctionArgs
& operator,(const T
& t
) {
82 /// Mark any reachable resources
84 /// This is only for cases where the lifetime of a FunctionArgs object
85 /// extends beyond a function call.
86 void setReachable() const {
87 std::for_each(_v
.begin(), _v
.end(),
88 std::mem_fun_ref(&as_value::setReachable
));
91 void swap(std::vector
<T
>& to
) {
95 size_type
size() const {
105 /// Parameters/environment for builtin or user-defined functions
106 /// callable from ActionScript.
111 typedef FunctionArgs
<as_value
> Args
;
113 /// Construct a fn_call
115 /// @param isNew Pass true if this is a constructing fn_call,
116 /// i.e. if it is called as a result of 'new'.
117 /// @param super Pass an overridden super value to the function
118 /// call. If this is 0, the super reference will be
119 /// calculated from the this pointer (if that is not
120 /// null) whenever a function requires it.
121 fn_call(as_object
* this_in
, const as_environment
& env_in
,
122 Args
& args
, as_object
* sup
= 0, bool isNew
= false)
134 fn_call(as_object
* this_in
, const as_environment
& env_in
)
146 fn_call(const fn_call
& fn
)
148 this_ptr(fn
.this_ptr
),
151 callerDef(fn
.callerDef
),
158 /// The as_object (or a pointer derived thereof) on which this call
162 /// The "super" object in this function call context
164 /// If this is 0, the super may be constructed from the this pointer.
167 /// Number of arguments to this ActionScript function call.
168 Args::size_type nargs
;
170 /// Definition containing caller code. 0 if spontaneous (system event).
171 const movie_definition
* callerDef
;
173 /// Return the VM this fn_call is running from
178 /// Return true if this call is an object instantiation
179 bool isInstantiation() const {
183 /// Access a particular argument.
184 const Args::value_type
& arg(unsigned int n
) const {
189 const Args::container_type
& getArgs() const {
194 assert(!_args
.empty());
195 _args
.erase(_args
.begin());
199 const as_environment
& env() const {
203 /// Dump arguments to given output stream
204 void dump_args(std::ostream
& os
) const {
205 for (size_t i
= 0; i
< nargs
; ++i
) {
216 void pushArg(const Args::value_type
& arg
) {
218 _args
.push_back(arg
);
223 /// The ActionScript environment in which the function call is taking
224 /// place. This contains, among other things, the function arguments.
225 const as_environment
& _env
;
227 /// The actual arguments
228 Args::container_type _args
;
235 /// Check that the 'this' pointer has a particular native type ('Relay').
237 /// This is the most likely of the cases to reflect AS behaviour.
241 typedef T value_type
;
242 value_type
* operator()(const as_object
* o
) const {
243 return dynamic_cast<value_type
*>(o
->relay());
247 /// Check that the 'this' pointer is a DisplayObject
249 /// By default this just checks for any DisplayObject type.
250 template<typename T
= DisplayObject
>
251 struct IsDisplayObject
253 typedef T value_type
;
254 value_type
* operator()(const as_object
* o
) const {
256 return dynamic_cast<T
*>(o
->displayObject());
260 /// Check that the 'this' pointer is not null.
263 typedef as_object value_type
;
264 value_type
* operator()(as_object
* o
) const {
269 /// Templated function to check the validity of a function call.
271 /// It throws an exception if the condition is not fulfilled, it throws
272 /// an ActionTypeError, resulting in the function call being aborted and
273 /// an undefined as_value returned.
275 /// Note that not carrying out a function because the this pointer is
276 /// undefined is not ActionScript behaviour in most cases. To avoid
277 /// spreading its usage outside AS function implementations, this function
278 /// now takes a fn_call as an argument.
280 /// @tparam T A struct defining a value_type and an operator() that
281 /// checks the as_object's validity. A pointer to the
282 /// value_type is returned on success, an exception thrown
284 /// @param fn The function whose 'this' pointer should be checked.
285 /// @return If the cast succeeds, the pointer cast to the
288 typename
T::value_type
*
289 ensure(const fn_call
& fn
)
291 as_object
* obj
= fn
.this_ptr
;
292 if (!obj
) throw ActionTypeError();
294 typename
T::value_type
* ret
= T()(obj
);
297 std::string target
= typeName(ret
);
298 std::string source
= typeName(obj
);
300 std::string msg
= "Function requiring " + target
+ " as 'this' "
301 "called from " + source
+ " instance.";
303 throw ActionTypeError(msg
);
309 getStringTable(const fn_call
& fn
)
311 return fn
.getVM().getStringTable();
315 getRoot(const fn_call
& fn
)
317 return fn
.getVM().getRoot();
321 getSWFVersion(const fn_call
& fn
)
323 return fn
.getVM().getSWFVersion();
327 getVM(const fn_call
& fn
)
333 getGlobal(const fn_call
& fn
)
335 return *fn
.getVM().getGlobal();
346 // indent-tabs-mode: nil