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.
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
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
)
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
;
46 if (super
->object
== NULL
) {
47 SWFDEC_WARNING ("super () called without an object.");
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
)->relay
)))
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
);
65 swfdec_as_super_class_init (SwfdecAsSuperClass
*klass
)
67 SwfdecAsFunctionClass
*function_class
= SWFDEC_AS_FUNCTION_CLASS (klass
);
69 function_class
->call
= swfdec_as_super_call
;
73 swfdec_as_super_init (SwfdecAsSuper
*super
)
78 swfdec_as_super_new (SwfdecAsFrame
*frame
, SwfdecAsObject
*thisp
, SwfdecAsObject
*ref
)
80 SwfdecAsContext
*context
;
81 SwfdecAsObject
*object
;
84 g_return_if_fail (frame
!= NULL
);
85 g_return_if_fail (thisp
!= NULL
);
87 if (frame
->super
!= NULL
)
89 context
= thisp
->context
;
90 if (context
->version
<= 5)
93 super
= g_object_new (SWFDEC_TYPE_AS_SUPER
, "context", context
, NULL
);
95 super
->thisp
= swfdec_as_object_resolve (thisp
);
96 if (context
->version
<= 5) {
102 object
= swfdec_as_object_new_empty (context
);
103 object
->super
= TRUE
;
104 swfdec_as_object_set_relay (object
, SWFDEC_AS_RELAY (super
));
108 swfdec_as_super_resolve_property (SwfdecAsSuper
*super
, const char *name
)
111 SwfdecAsContext
*context
;
113 g_return_val_if_fail (SWFDEC_IS_AS_SUPER (super
), NULL
);
115 if (super
->object
== NULL
)
117 ref
= super
->object
->prototype
;
120 context
= swfdec_gc_object_get_context (super
);
121 if (name
&& context
->version
> 6) {
122 /* skip prototypes to find the next one that has this function defined */
124 if (swfdec_as_object_get_variable_and_flags (ref
,
125 name
, NULL
, NULL
, &res
) && ref
!= res
) {
126 while (ref
->prototype
!= res
) {
127 ref
= ref
->prototype
;