move script function specific code to the right file
[swfdec.git] / swfdec / swfdec_as_function.c
blob1cb573d04c69b256f757444c7c3e0b54eb3fec9f
1 /* Swfdec
2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "swfdec_as_function.h"
25 #include "swfdec_as_context.h"
26 #include "swfdec_as_internal.h"
27 #include "swfdec_as_native_function.h"
28 #include "swfdec_as_strings.h"
29 #include "swfdec_debug.h"
31 G_DEFINE_ABSTRACT_TYPE (SwfdecAsFunction, swfdec_as_function, SWFDEC_TYPE_AS_OBJECT)
33 /**
34 * SECTION:SwfdecAsFunction
35 * @title: SwfdecAsFunction
36 * @short_description: script objects that can be executed
38 * Functions is the basic object for executing code in the Swfdec script engine.
39 * There is multiple different variants of functions, such as script-created
40 * ones and native functions.
42 * If you want to create your own functions, you should create native functions.
43 * The easiest way to do this is with swfdec_as_object_add_function() or
44 * swfdec_as_native_function_new().
46 * In Actionscript, every function can be used as a constructor. If you want to
47 * make a native function be used as a constructor for your own #SwfdecAsObject
48 * subclass, have a look at swfdec_as_native_function_set_construct_type().
51 /**
52 * SwfdecAsFunction
54 * This is the base executable object in Swfdec. It is an abstract object. If
55 * you want to create functions yourself, use #SwfdecAsNativeFunction.
58 static void
59 swfdec_as_function_class_init (SwfdecAsFunctionClass *klass)
63 static void
64 swfdec_as_function_init (SwfdecAsFunction *function)
68 /**
69 * swfdec_as_function_set_constructor:
70 * @fun: a #SwfdecAsFunction
72 * Sets the constructor and prototype of @fun. This is a shortcut for calling
73 * swfdec_as_object_set_constructor() with the right arguments.
74 **/
75 void
76 swfdec_as_function_set_constructor (SwfdecAsFunction *fun)
78 SwfdecAsContext *context;
79 SwfdecAsObject *object;
80 SwfdecAsValue val;
82 g_return_if_fail (SWFDEC_IS_AS_FUNCTION (fun));
84 object = SWFDEC_AS_OBJECT (fun);
85 context = swfdec_gc_object_get_context (fun);
86 if (context->Function == NULL)
87 return;
89 SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
90 swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_constructor,
91 &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
93 SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function_prototype);
94 swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___proto__,
95 &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT |
96 SWFDEC_AS_VARIABLE_VERSION_6_UP);
99 /**
100 * swfdec_as_function_call:
101 * @function: the #SwfdecAsFunction to call
102 * @thisp: this argument to use for the call or %NULL for none
103 * @n_args: number of arguments to pass to the function
104 * @args: the arguments to pass or %NULL to read the last @n_args stack elements.
105 * @return_value: pointer for return value or %NULL to push the return value to
106 * the stack
108 * Calls the given function. This is a macro that resolves to
109 * swfdec_as_function_call_full().
112 * swfdec_as_function_call_full:
113 * @function: the #SwfdecAsFunction to call
114 * @thisp: this argument to use for the call or %NULL for none
115 * @construct: call this function as a constructor. This is only relevant for
116 * native functions.
117 * @super_reference: The object to be referenced by the super object in this
118 * function call or %NULL to use the default.
119 * @n_args: number of arguments to pass to the function
120 * @args: the arguments to pass or %NULL to read the last @n_args stack elements.
121 * @return_value: pointer for return value or %NULL to push the return value to
122 * the stack
124 * Calls the given function.
126 void
127 swfdec_as_function_call_full (SwfdecAsFunction *function, SwfdecAsObject *thisp,
128 gboolean construct, SwfdecAsObject *super_reference, guint n_args,
129 const SwfdecAsValue *args, SwfdecAsValue *return_value)
131 SwfdecAsFunctionClass *klass;
133 g_return_if_fail (SWFDEC_IS_AS_FUNCTION (function));
134 g_return_if_fail (thisp == NULL || SWFDEC_IS_AS_OBJECT (thisp));
135 g_return_if_fail (super_reference == NULL || SWFDEC_IS_AS_OBJECT (super_reference));
137 klass = SWFDEC_AS_FUNCTION_GET_CLASS (function);
138 klass->call (function, thisp, construct, super_reference, n_args, args, return_value);
141 /*** AS CODE ***/
143 SWFDEC_AS_NATIVE (101, 10, swfdec_as_function_do_call)
144 void
145 swfdec_as_function_do_call (SwfdecAsContext *cx, SwfdecAsObject *object,
146 guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
148 SwfdecAsFunction *fun;
149 SwfdecAsObject *thisp = NULL;
151 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_FUNCTION, &fun, "|O", &thisp);
153 if (thisp == NULL) {
154 thisp = swfdec_as_object_new_empty (cx);
156 if (argc > 0) {
157 argc--;
158 argv++;
160 swfdec_as_function_call (fun, thisp, argc, argv, ret);
163 SWFDEC_AS_NATIVE (101, 11, swfdec_as_function_apply)
164 void
165 swfdec_as_function_apply (SwfdecAsContext *cx, SwfdecAsObject *object,
166 guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
168 SwfdecAsValue *argv_pass = NULL;
169 int length = 0;
170 SwfdecAsFunction *fun;
171 SwfdecAsObject *thisp = NULL;
173 SWFDEC_AS_CHECK (SWFDEC_TYPE_AS_FUNCTION, &fun, "|O", &thisp);
175 if (thisp == NULL)
176 thisp = swfdec_as_object_new_empty (cx);
178 if (argc > 1 && SWFDEC_AS_VALUE_IS_OBJECT (&argv[1])) {
179 int i;
180 SwfdecAsObject *array;
181 SwfdecAsValue val;
183 array = SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]);
185 swfdec_as_object_get_variable (array, SWFDEC_AS_STR_length, &val);
186 length = swfdec_as_value_to_integer (cx, &val);
188 if (length > 0) {
189 /* FIXME: find a smarter way to do this, like providing argv not as an array */
190 if (!swfdec_as_context_try_use_mem (cx, sizeof (SwfdecAsValue) * length)) {
191 swfdec_as_context_abort (cx, "too many arguments to Function.apply");
192 return;
194 argv_pass = g_malloc (sizeof (SwfdecAsValue) * length);
196 for (i = 0; i < length; i++) {
197 swfdec_as_object_get_variable (array,
198 swfdec_as_integer_to_string (cx, i), &argv_pass[i]);
200 } else {
201 length = 0;
205 swfdec_as_function_call (fun, thisp, length, argv_pass, ret);
207 if (argv_pass) {
208 swfdec_as_context_unuse_mem (cx, sizeof (SwfdecAsValue) * length);
209 g_free (argv_pass);
213 void
214 swfdec_as_function_init_context (SwfdecAsContext *context)
216 SwfdecAsObject *function, *proto;
217 SwfdecAsValue val;
219 g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
221 function = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
222 SWFDEC_AS_STR_Function, NULL));
223 swfdec_as_object_set_variable_flags (context->global, SWFDEC_AS_STR_Function, SWFDEC_AS_VARIABLE_VERSION_6_UP);
224 context->Function = function;
225 SWFDEC_AS_VALUE_SET_OBJECT (&val, function);
226 swfdec_as_object_set_variable_and_flags (function, SWFDEC_AS_STR_constructor,
227 &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
228 proto = swfdec_as_object_new_empty (context);
229 context->Function_prototype = proto;
230 SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
231 swfdec_as_object_set_variable_and_flags (function, SWFDEC_AS_STR_prototype,
232 &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
233 swfdec_as_object_set_variable_and_flags (function, SWFDEC_AS_STR___proto__,
234 &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT |
235 SWFDEC_AS_VARIABLE_VERSION_6_UP);
236 SWFDEC_AS_VALUE_SET_OBJECT (&val, function);
237 swfdec_as_object_set_variable_and_flags (proto, SWFDEC_AS_STR_constructor,
238 &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);