get rid of debugger bits
[swfdec.git] / libswfdec / swfdec_as_function.c
blob879ed9d0e0fbe732ea9795596c0f49409027ba94
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_frame_internal.h"
27 #include "swfdec_as_internal.h"
28 #include "swfdec_as_stack.h"
29 #include "swfdec_as_strings.h"
30 #include "swfdec_debug.h"
32 G_DEFINE_ABSTRACT_TYPE (SwfdecAsFunction, swfdec_as_function, SWFDEC_TYPE_AS_OBJECT)
34 /**
35 * SECTION:SwfdecAsFunction
36 * @title: SwfdecAsFunction
37 * @short_description: script objects that can be executed
39 * Functions is the basic object for executing code in the Swfdec script engine.
40 * There is multiple different variants of functions, such as script-created
41 * ones and native functions.
43 * If you want to create your own functions, you should create native functions.
44 * The easiest way to do this is with swfdec_as_object_add_function() or
45 * swfdec_as_native_function_new().
47 * In Actionscript, every function can be used as a constructor. If you want to
48 * make a native function be used as a constructor for your own #SwfdecAsObject
49 * subclass, have a look at swfdec_as_native_function_set_construct_type().
52 /**
53 * SwfdecAsFunction
55 * This is the base executable object in Swfdec. It is an abstract object. If
56 * you want to create functions yourself, use #SwfdecAsNativeFunction.
59 static void
60 swfdec_as_function_class_init (SwfdecAsFunctionClass *klass)
64 static void
65 swfdec_as_function_init (SwfdecAsFunction *function)
69 /**
70 * swfdec_as_function_set_constructor:
71 * @fun: a #SwfdecAsFunction
73 * Sets the constructor and prototype of @fun. This is a shortcut for calling
74 * swfdec_as_object_set_constructor() with the right arguments.
75 **/
76 void
77 swfdec_as_function_set_constructor (SwfdecAsFunction *fun)
79 SwfdecAsContext *context;
80 SwfdecAsObject *object;
81 SwfdecAsValue val;
83 g_return_if_fail (SWFDEC_IS_AS_FUNCTION (fun));
85 object = SWFDEC_AS_OBJECT (fun);
86 context = object->context;
87 if (context->Function) {
88 SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
89 swfdec_as_object_set_variable (object, SWFDEC_AS_STR_constructor, &val);
91 if (context->Function_prototype) {
92 SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function_prototype);
93 swfdec_as_object_set_variable (object, SWFDEC_AS_STR___proto__, &val);
97 /**
98 * swfdec_as_function_call:
99 * @function: the #SwfdecAsFunction to call
100 * @thisp: this argument to use for the call or %NULL for none
101 * @n_args: number of arguments to pass to the function
102 * @args: the arguments to pass or %NULL to read the last @n_args stack elements
103 * @return_value: pointer for return value or %NULL to push the return value to
104 * the stack
106 * Calls the given function. This means a #SwfdecAsFrame is created for the
107 * function and pushed on top of the execution stack. The function is however
108 * not executed. Call swfdec_as_context_run () to execute it.
110 void
111 swfdec_as_function_call (SwfdecAsFunction *function, SwfdecAsObject *thisp, guint n_args,
112 const SwfdecAsValue *args, SwfdecAsValue *return_value)
114 SwfdecAsContext *context;
115 SwfdecAsFrame *frame;
116 SwfdecAsFunctionClass *klass;
118 g_return_if_fail (SWFDEC_IS_AS_FUNCTION (function));
119 g_return_if_fail (thisp == NULL || SWFDEC_IS_AS_OBJECT (thisp));
121 context = SWFDEC_AS_OBJECT (function)->context;
122 /* just to be sure... */
123 if (return_value)
124 SWFDEC_AS_VALUE_SET_UNDEFINED (return_value);
126 klass = SWFDEC_AS_FUNCTION_GET_CLASS (function);
127 g_assert (klass->call);
128 frame = klass->call (function);
129 /* FIXME: figure out what to do in these situations */
130 if (frame == NULL)
131 return;
132 /* second check especially for super object */
133 if (thisp != NULL && frame->thisp == NULL)
134 swfdec_as_frame_set_this (frame, swfdec_as_object_resolve (thisp));
135 frame->is_local = TRUE;
136 frame->argc = n_args;
137 frame->argv = args;
138 frame->return_value = return_value;
139 swfdec_as_frame_preload (frame);
142 /*** AS CODE ***/
144 static void
145 swfdec_as_function_do_call (SwfdecAsContext *context, SwfdecAsObject *fun,
146 guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
148 SwfdecAsObject *thisp;
150 if (argc > 0) {
151 thisp = swfdec_as_value_to_object (context, &argv[0]);
152 argc -= 1;
153 argv++;
154 } else {
155 thisp = NULL;
157 if (thisp == NULL)
158 thisp = swfdec_as_object_new_empty (context);
159 swfdec_as_function_call (SWFDEC_AS_FUNCTION (fun), thisp, argc, argv, ret);
160 swfdec_as_context_run (context);
163 void
164 swfdec_as_function_init_context (SwfdecAsContext *context, guint version)
166 SwfdecAsObject *function, *proto;
167 SwfdecAsValue val;
169 g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
171 function = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
172 SWFDEC_AS_STR_Function, 0, NULL, 0));
173 if (!function)
174 return;
175 if (version < 6) {
176 /* deleting it later on is easier than duplicating swfdec_as_object_add_function() */
177 swfdec_as_object_delete_variable (context->global, SWFDEC_AS_STR_Function);
179 context->Function = function;
180 SWFDEC_AS_VALUE_SET_OBJECT (&val, function);
181 swfdec_as_object_set_variable (function, SWFDEC_AS_STR_constructor, &val);
182 if (version > 5) {
183 proto = swfdec_as_object_new_empty (context);
184 if (!proto)
185 return;
186 context->Function_prototype = proto;
187 SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
188 swfdec_as_object_set_variable (function, SWFDEC_AS_STR___proto__, &val);
189 swfdec_as_object_set_variable (function, SWFDEC_AS_STR_prototype, &val);
190 /* prototype functions */
191 swfdec_as_object_add_function (proto, SWFDEC_AS_STR_call, SWFDEC_TYPE_AS_FUNCTION,
192 swfdec_as_function_do_call, 0);