make numbers garbage-collected objects
[swfdec.git] / swfdec / swfdec_as_super.c
blob6975bc11a06d7c28ede6fe81d1b3c29b76bee01d
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 <math.h>
26 #include "swfdec_as_super.h"
27 #include "swfdec_as_context.h"
28 #include "swfdec_as_frame_internal.h"
29 #include "swfdec_as_function.h"
30 #include "swfdec_as_internal.h"
31 #include "swfdec_as_strings.h"
32 #include "swfdec_debug.h"
33 #include "swfdec_movie.h"
35 G_DEFINE_TYPE (SwfdecAsSuper, swfdec_as_super, SWFDEC_TYPE_AS_FUNCTION)
37 static void
38 swfdec_as_super_call (SwfdecAsFunction *function, SwfdecAsObject *thisp,
39 gboolean construct, SwfdecAsObject *super_reference, guint n_args,
40 const SwfdecAsValue *args, SwfdecAsValue *return_value)
42 SwfdecAsSuper *super = SWFDEC_AS_SUPER (function);
43 SwfdecAsFunction *fun;
44 SwfdecAsValue val;
46 if (super->object == NULL) {
47 SWFDEC_WARNING ("super () called without an object.");
48 return;
51 swfdec_as_object_get_variable (super->object, SWFDEC_AS_STR___constructor__, &val);
52 if (!SWFDEC_AS_VALUE_IS_OBJECT (&val) ||
53 !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val)))
54 return;
56 if (construct) {
57 SWFDEC_FIXME ("What happens with \"new super()\"?");
59 swfdec_as_function_call_full (fun, super->thisp, construct ||
60 swfdec_as_context_is_constructing (swfdec_gc_object_get_context (super)),
61 super->object->prototype, n_args, args, return_value);
64 static gboolean
65 swfdec_as_super_get (SwfdecAsObject *object, SwfdecAsObject *orig,
66 const char *variable, SwfdecAsValue *val, guint *flags)
68 SwfdecAsSuper *super = SWFDEC_AS_SUPER (object);
69 SwfdecAsObjectClass *klass;
70 SwfdecAsObject *cur;
71 guint i;
73 if (super->object == NULL) {
74 SWFDEC_WARNING ("super.%s () called without an object.", variable);
75 return FALSE;
77 cur = super->object->prototype;
78 for (i = 0; i <= SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT && cur != NULL; i++) {
79 klass = SWFDEC_AS_OBJECT_GET_CLASS (cur);
80 /* FIXME: is the orig pointer correct? */
81 if (klass->get (cur, super->object, variable, val, flags))
82 return TRUE;
83 /* FIXME: need get_prototype_internal here? */
84 cur = swfdec_as_object_get_prototype (cur);
86 if (i > SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT) {
87 swfdec_as_context_abort (swfdec_gc_object_get_context (object),
88 "Prototype recursion limit exceeded");
90 SWFDEC_AS_VALUE_SET_UNDEFINED (val);
91 *flags = 0;
92 return FALSE;
95 static void
96 swfdec_as_super_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val, guint flags)
98 /* This seems to be ignored completely */
101 static void
102 swfdec_as_super_set_flags (SwfdecAsObject *object, const char *variable, guint flags, guint mask)
104 /* if we have no variables, we also can't set its flags... */
107 static SwfdecAsDeleteReturn
108 swfdec_as_super_delete (SwfdecAsObject *object, const char *variable)
110 /* if we have no variables... */
111 return SWFDEC_AS_DELETE_NOT_FOUND;
114 static SwfdecAsObject *
115 swfdec_as_super_resolve (SwfdecAsObject *object)
117 SwfdecAsSuper *super = SWFDEC_AS_SUPER (object);
119 return super->thisp;
122 static void
123 swfdec_as_super_class_init (SwfdecAsSuperClass *klass)
125 SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass);
126 SwfdecAsFunctionClass *function_class = SWFDEC_AS_FUNCTION_CLASS (klass);
128 asobject_class->get = swfdec_as_super_get;
129 asobject_class->set = swfdec_as_super_set;
130 asobject_class->set_flags = swfdec_as_super_set_flags;
131 asobject_class->del = swfdec_as_super_delete;
132 asobject_class->resolve = swfdec_as_super_resolve;
134 function_class->call = swfdec_as_super_call;
137 static void
138 swfdec_as_super_init (SwfdecAsSuper *super)
142 void
143 swfdec_as_super_new (SwfdecAsFrame *frame, SwfdecAsObject *thisp, SwfdecAsObject *ref)
145 SwfdecAsContext *context;
146 SwfdecAsSuper *super;
148 g_return_if_fail (frame != NULL);
149 g_return_if_fail (SWFDEC_IS_AS_OBJECT (thisp));
150 g_return_if_fail (ref == NULL || SWFDEC_IS_AS_OBJECT (ref));
152 if (frame->super != NULL)
153 return;
154 context = swfdec_gc_object_get_context (thisp);
155 if (context->version <= 5)
156 return;
158 super = g_object_new (SWFDEC_TYPE_AS_SUPER, "context", context, NULL);
159 frame->super = SWFDEC_AS_OBJECT (super);
160 super->thisp = swfdec_as_object_resolve (thisp);
161 if (context->version <= 5) {
162 super->object = NULL;
163 } else {
164 super->object = ref;
168 SwfdecAsObject *
169 swfdec_as_super_resolve_property (SwfdecAsSuper *super, const char *name)
171 SwfdecAsObject *ref;
172 SwfdecAsContext *context;
174 g_return_val_if_fail (SWFDEC_IS_AS_SUPER (super), NULL);
176 if (super->object == NULL)
177 return NULL;
178 ref = super->object->prototype;
179 if (ref == NULL)
180 return NULL;
181 context = swfdec_gc_object_get_context (super);
182 if (name && context->version > 6) {
183 /* skip prototypes to find the next one that has this function defined */
184 SwfdecAsObject *res;
185 if (swfdec_as_object_get_variable_and_flags (ref,
186 name, NULL, NULL, &res) && ref != res) {
187 while (ref->prototype != res) {
188 ref = ref->prototype;
189 g_assert (ref);
193 return ref;