Benjamin Otte
2007-May-18 15:30 UTC
[Swfdec] Branch 'as' - libswfdec/Makefile.am libswfdec/swfdec_as_context.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_native_function.h libswfdec/swfdec_as_number.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_script_function.c libswfdec/swfdec_as_script_function.h
libswfdec/Makefile.am | 4 + libswfdec/swfdec_as_context.c | 10 +- libswfdec/swfdec_as_function.c | 130 +++------------------------------- libswfdec/swfdec_as_function.h | 28 +------ libswfdec/swfdec_as_interpret.c | 7 + libswfdec/swfdec_as_native_function.c | 113 +++++++++++++++++++++++++++++ libswfdec/swfdec_as_native_function.h | 68 +++++++++++++++++ libswfdec/swfdec_as_number.c | 5 - libswfdec/swfdec_as_object.c | 40 ++++++++-- libswfdec/swfdec_as_script_function.c | 110 ++++++++++++++++++++++++++++ libswfdec/swfdec_as_script_function.h | 59 +++++++++++++++ 11 files changed, 422 insertions(+), 152 deletions(-) New commits: diff-tree 91444350cb32843ed2aa0ea386df0ba983a7aec6 (from 40299761a60e06300ee005332213d19f413e2cf7) Author: Benjamin Otte <otte at gnome.org> Date: Fri May 18 17:29:26 2007 +0200 split up function object native and script functions are two different objects now. Also includes fixes to how object types are handled. diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am index 2bfc151..7cf86f6 100644 --- a/libswfdec/Makefile.am +++ b/libswfdec/Makefile.am @@ -37,9 +37,11 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES swfdec_as_frame.c \ swfdec_as_function.c \ swfdec_as_interpret.c \ + swfdec_as_native_function.c \ swfdec_as_number.c \ swfdec_as_object.c \ swfdec_as_scope.c \ + swfdec_as_script_function.c \ swfdec_as_stack.c \ swfdec_as_strings.c \ swfdec_as_super.c \ @@ -135,9 +137,11 @@ noinst_HEADERS = \ swfdec_as_frame.h \ swfdec_as_function.h \ swfdec_as_interpret.h \ + swfdec_as_native_function.h \ swfdec_as_number.h \ swfdec_as_object.h \ swfdec_as_scope.h \ + swfdec_as_script_function.h \ swfdec_as_stack.h \ swfdec_as_strings.h \ swfdec_as_super.h \ diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c index 43f7c46..9f07f55 100644 --- a/libswfdec/swfdec_as_context.c +++ b/libswfdec/swfdec_as_context.c @@ -28,6 +28,7 @@ #include "swfdec_as_frame.h" #include "swfdec_as_function.h" #include "swfdec_as_interpret.h" +#include "swfdec_as_native_function.h" #include "swfdec_as_number.h" #include "swfdec_as_object.h" #include "swfdec_as_stack.h" @@ -389,10 +390,11 @@ start: frame = context->frame; if (frame == context->last_frame) goto out; - if (frame->function && frame->function->native) { - if (frame->argc >= frame->function->min_args && - g_type_is_a (G_OBJECT_TYPE (frame->thisp), frame->function->type)) { - frame->function->native (frame->thisp, frame->argc, frame->argv, frame->return_value); + if (SWFDEC_IS_AS_NATIVE_FUNCTION (frame->function)) { + SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (frame->function); + if (frame->argc >= native->min_args && + (native->type == 0 || g_type_is_a (G_OBJECT_TYPE (frame->thisp), native->type))) { + native->native (frame->thisp, frame->argc, frame->argv, frame->return_value); } swfdec_as_context_return (context); goto start; diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c index c6a7c92..dd91fcc 100644 --- a/libswfdec/swfdec_as_function.c +++ b/libswfdec/swfdec_as_function.c @@ -27,63 +27,32 @@ #include "swfdec_as_stack.h" #include "swfdec_debug.h" -G_DEFINE_TYPE (SwfdecAsFunction, swfdec_as_function, SWFDEC_TYPE_AS_OBJECT) - -static void -swfdec_as_function_dispose (GObject *object) -{ - SwfdecAsFunction *function = SWFDEC_AS_FUNCTION (object); - - if (function->script) { - swfdec_script_unref (function->script); - function->script = NULL; - } - g_free (function->name); - function->name = NULL; - - G_OBJECT_CLASS (swfdec_as_function_parent_class)->dispose (object); -} - -static void -swfdec_as_function_mark (SwfdecAsObject *object) -{ - SwfdecAsFunction *function = SWFDEC_AS_FUNCTION (object); - - if (function->scope) - swfdec_as_object_mark (SWFDEC_AS_OBJECT (function->scope)); - - SWFDEC_AS_OBJECT_CLASS (swfdec_as_function_parent_class)->mark (object); -} +G_DEFINE_ABSTRACT_TYPE (SwfdecAsFunction, swfdec_as_function, SWFDEC_TYPE_AS_OBJECT) static void swfdec_as_function_class_init (SwfdecAsFunctionClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); - - object_class->dispose = swfdec_as_function_dispose; - - asobject_class->mark = swfdec_as_function_mark; } static void swfdec_as_function_init (SwfdecAsFunction *function) { - function->type = SWFDEC_TYPE_AS_OBJECT; - function->type_size = sizeof (SwfdecAsObject); } SwfdecAsFunction * -swfdec_as_function_do_create (SwfdecAsContext *context) +swfdec_as_function_create (SwfdecAsContext *context, GType type, guint size) { SwfdecAsValue val; SwfdecAsObject *fun; - if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsFunction))) + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); + g_return_val_if_fail (g_type_is_a (type, SWFDEC_TYPE_AS_FUNCTION), NULL); + g_return_val_if_fail (size >= sizeof (SwfdecAsFunction), NULL); + + if (!swfdec_as_context_use_mem (context, size)) return NULL; - fun = g_object_new (SWFDEC_TYPE_AS_FUNCTION, NULL); - swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, sizeof (SwfdecAsFunction)); - swfdec_as_object_root (fun); + fun = g_object_new (type, NULL); + swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, size); if (context->Function) { SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function); swfdec_as_object_set_variable (fun, SWFDEC_AS_STR_constructor, &val); @@ -92,60 +61,17 @@ swfdec_as_function_do_create (SwfdecAsCo SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function_prototype); swfdec_as_object_set_variable (fun, SWFDEC_AS_STR___proto__, &val); } - swfdec_as_object_unroot (fun); return SWFDEC_AS_FUNCTION (fun); } -SwfdecAsFunction * -swfdec_as_function_new (SwfdecAsScope *scope) -{ - SwfdecAsValue val; - SwfdecAsFunction *fun; - SwfdecAsObject *proto; - - g_return_val_if_fail (SWFDEC_IS_AS_SCOPE (scope), NULL); - - fun = swfdec_as_function_do_create (SWFDEC_AS_OBJECT (scope)->context); - if (fun == NULL) - return NULL; - proto = swfdec_as_object_new (SWFDEC_AS_OBJECT (scope)->context); - if (proto == NULL) - return NULL; - SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (fun)); - swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val); - SWFDEC_AS_VALUE_SET_OBJECT (&val, proto); - swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, &val); - fun->scope = scope; - - return fun; -} - -SwfdecAsFunction * -swfdec_as_function_new_native (SwfdecAsContext *context, const char *name, - SwfdecAsNative native, guint min_args) -{ - SwfdecAsFunction *fun; - - g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); - g_return_val_if_fail (native != NULL, NULL); - - fun = swfdec_as_function_do_create (context); - if (fun == NULL) - return NULL; - fun->native = native; - fun->min_args = min_args; - fun->name = g_strdup (name); - - return fun; -} - void swfdec_as_function_call (SwfdecAsFunction *function, SwfdecAsObject *thisp, guint n_args, SwfdecAsValue *args, SwfdecAsValue *return_value) { SwfdecAsContext *context; SwfdecAsFrame *frame; + SwfdecAsFunctionClass *klass; g_return_if_fail (SWFDEC_IS_AS_FUNCTION (function)); g_return_if_fail (SWFDEC_IS_AS_OBJECT (thisp)); @@ -153,16 +79,12 @@ swfdec_as_function_call (SwfdecAsFunctio g_return_if_fail (return_value != NULL); context = thisp->context; + /* just to be sure... */ SWFDEC_AS_VALUE_SET_UNDEFINED (return_value); - if (function->native) { - frame = swfdec_as_frame_new_native (thisp); - g_assert (function->name); - frame->function_name = function->name; - } else { - frame = swfdec_as_frame_new (thisp, function->script); - SWFDEC_AS_SCOPE (frame)->next = function->scope; - frame->scope = SWFDEC_AS_SCOPE (frame); - } + klass = SWFDEC_AS_FUNCTION_GET_CLASS (function); + g_assert (klass->call); + klass->call (function, thisp); + frame = context->frame; frame->var_object = SWFDEC_AS_OBJECT (frame); frame->argc = n_args; frame->argv = args; @@ -171,28 +93,6 @@ swfdec_as_function_call (SwfdecAsFunctio swfdec_as_frame_preload (frame); } -/** - * swfdec_as_function_set_object_type: - * @function: a native #SwfdecAsFunction - * @type: required #GType for this object - * - * Sets the required type for the this object to @type. If the this object - * isn't of the required type, the function will not be called and its - * return value will be undefined. - **/ -void -swfdec_as_function_set_object_type (SwfdecAsFunction *function, GType type) -{ - GTypeQuery query; - - g_return_if_fail (SWFDEC_IS_AS_FUNCTION (function)); - g_return_if_fail (g_type_is_a (type, SWFDEC_TYPE_AS_OBJECT)); - - g_type_query (type, &query); - function->type = type; - function->type_size = query.instance_size; -} - /*** AS CODE ***/ static void diff --git a/libswfdec/swfdec_as_function.h b/libswfdec/swfdec_as_function.h index a6041c4..951911e 100644 --- a/libswfdec/swfdec_as_function.h +++ b/libswfdec/swfdec_as_function.h @@ -38,36 +38,22 @@ typedef struct _SwfdecAsFunctionClass Sw /* FIXME: do two obejcts, one for scripts and one for native? */ struct _SwfdecAsFunction { SwfdecAsObject object; - - /* for native functions */ - SwfdecAsNative native; /* native call or NULL when script */ - guint min_args; /* minimum number of required arguments */ - char * name; /* function name */ - - /* for script functions */ - SwfdecScript * script; /* script being executed or NULL when native */ - SwfdecAsScope * scope; /* scope this function was defined in or NULL */ - - /* constructor info */ - GType type; /* required type for this object when caling function */ - guint type_size; /* instance size of type */ }; struct _SwfdecAsFunctionClass { SwfdecAsObjectClass object_class; + + /* call this function: push a new frame onto the stack */ + void (* call) (SwfdecAsFunction * function, + SwfdecAsObject * thisp); }; GType swfdec_as_function_get_type (void); -/* FIXME: verify what scope a function gets that is defined inside a With statement */ -SwfdecAsFunction * swfdec_as_function_new (SwfdecAsScope * scope); -SwfdecAsFunction * swfdec_as_function_new_native (SwfdecAsContext * context, - const char * name, - SwfdecAsNative native, - guint min_args); +SwfdecAsFunction * swfdec_as_function_create (SwfdecAsContext * context, + GType type, + guint size); -void swfdec_as_function_set_object_type (SwfdecAsFunction * function, - GType type); void swfdec_as_function_call (SwfdecAsFunction * function, SwfdecAsObject * thisp, guint n_args, diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c index 832a2e3..acdfb74 100644 --- a/libswfdec/swfdec_as_interpret.c +++ b/libswfdec/swfdec_as_interpret.c @@ -25,6 +25,7 @@ #include "swfdec_as_context.h" #include "swfdec_as_frame.h" #include "swfdec_as_function.h" +#include "swfdec_as_script_function.h" #include "swfdec_as_stack.h" #include "swfdec_debug.h" @@ -1266,12 +1267,12 @@ swfdec_action_define_function (SwfdecAsC } /* see function-scope tests */ if (cx->version > 5) { - fun = swfdec_as_function_new (frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame)); + fun = swfdec_as_script_function_new (frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame)); } else { SwfdecAsScope *scope = frame->scope ? frame->scope : SWFDEC_AS_SCOPE (frame); while (scope->next) scope = scope->next; - fun = swfdec_as_function_new (scope); + fun = swfdec_as_script_function_new (scope); } if (fun == NULL) return; @@ -1342,7 +1343,7 @@ swfdec_action_define_function (SwfdecAsC script->n_registers = n_registers; script->n_arguments = n_args; script->arguments = args; - fun->script = script; + SWFDEC_AS_SCRIPT_FUNCTION (fun)->script = script; swfdec_script_add_to_context (script, cx); /* attach the function */ if (*function_name == '\0') { diff --git a/libswfdec/swfdec_as_native_function.c b/libswfdec/swfdec_as_native_function.c new file mode 100644 index 0000000..b373e3a --- /dev/null +++ b/libswfdec/swfdec_as_native_function.c @@ -0,0 +1,113 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte at gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "swfdec_as_native_function.h" +#include "swfdec_as_context.h" +#include "swfdec_as_frame.h" +#include "swfdec_as_stack.h" +#include "swfdec_debug.h" + +G_DEFINE_TYPE (SwfdecAsNativeFunction, swfdec_as_native_function, SWFDEC_TYPE_AS_FUNCTION) + +static void +swfdec_as_native_function_call (SwfdecAsFunction *function, SwfdecAsObject *thisp) +{ + SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (function); + SwfdecAsFrame *frame; + + frame = swfdec_as_frame_new_native (thisp); + g_assert (native->name); + frame->function_name = native->name; +} + +static void +swfdec_as_native_function_dispose (GObject *object) +{ + SwfdecAsNativeFunction *function = SWFDEC_AS_NATIVE_FUNCTION (object); + + g_free (function->name); + function->name = NULL; + + G_OBJECT_CLASS (swfdec_as_native_function_parent_class)->dispose (object); +} + +static void +swfdec_as_native_function_class_init (SwfdecAsNativeFunctionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfdecAsFunctionClass *function_class = SWFDEC_AS_FUNCTION_CLASS (klass); + + object_class->dispose = swfdec_as_native_function_dispose; + + function_class->call = swfdec_as_native_function_call; +} + +static void +swfdec_as_native_function_init (SwfdecAsNativeFunction *function) +{ +} + +SwfdecAsFunction * +swfdec_as_native_function_new (SwfdecAsContext *context, const char *name, + SwfdecAsNative native, guint min_args) +{ + SwfdecAsNativeFunction *nfun; + SwfdecAsFunction *fun; + + g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL); + g_return_val_if_fail (native != NULL, NULL); + + fun = swfdec_as_function_create (context, SWFDEC_TYPE_AS_NATIVE_FUNCTION, + sizeof (SwfdecAsNativeFunction)); + if (fun == NULL) + return NULL; + nfun = SWFDEC_AS_NATIVE_FUNCTION (fun); + nfun->native = native; + nfun->min_args = min_args; + nfun->name = g_strdup (name); + + return fun; +} + +/** + * swfdec_as_native_function_set_object_type: + * @function: a native #SwfdecAsNativeFunction + * @type: required #GType for this object + * + * Sets the required type for the this object to @type. If the this object + * isn't of the required type, the function will not be called and its + * return value will be undefined. + **/ +void +swfdec_as_native_function_set_object_type (SwfdecAsNativeFunction *function, GType type) +{ + GTypeQuery query; + + g_return_if_fail (SWFDEC_IS_AS_NATIVE_FUNCTION (function)); + g_return_if_fail (g_type_is_a (type, SWFDEC_TYPE_AS_OBJECT)); + + g_type_query (type, &query); + function->type = type; + function->type_size = query.instance_size; +} + diff --git a/libswfdec/swfdec_as_native_function.h b/libswfdec/swfdec_as_native_function.h new file mode 100644 index 0000000..960bcc7 --- /dev/null +++ b/libswfdec/swfdec_as_native_function.h @@ -0,0 +1,68 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte at gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef _SWFDEC_AS_NATIVE_FUNCTION_H_ +#define _SWFDEC_AS_NATIVE_FUNCTION_H_ + +#include <libswfdec/swfdec_as_function.h> +#include <libswfdec/swfdec_as_types.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecAsNativeFunction SwfdecAsNativeFunction; +typedef struct _SwfdecAsNativeFunctionClass SwfdecAsNativeFunctionClass; + +#define SWFDEC_TYPE_AS_NATIVE_FUNCTION (swfdec_as_native_function_get_type()) +#define SWFDEC_IS_AS_NATIVE_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_NATIVE_FUNCTION)) +#define SWFDEC_IS_AS_NATIVE_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_NATIVE_FUNCTION)) +#define SWFDEC_AS_NATIVE_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_NATIVE_FUNCTION, SwfdecAsNativeFunction)) +#define SWFDEC_AS_NATIVE_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_NATIVE_FUNCTION, SwfdecAsNativeFunctionClass)) +#define SWFDEC_AS_NATIVE_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_NATIVE_FUNCTION, SwfdecAsNativeFunctionClass)) + +/* FIXME: do two obejcts, one for scripts and one for native? */ +struct _SwfdecAsNativeFunction { + SwfdecAsFunction function; + + SwfdecAsNative native; /* native call or NULL when script */ + guint min_args; /* minimum number of required arguments */ + char * name; /* function name */ + + /* constructor info */ + GType type; /* required type for this object when caling function */ + guint type_size; /* instance size of type */ +}; + +struct _SwfdecAsNativeFunctionClass { + SwfdecAsFunctionClass function_class; +}; + +GType swfdec_as_native_function_get_type (void); + +SwfdecAsFunction *swfdec_as_native_function_new (SwfdecAsContext * context, + const char * name, + SwfdecAsNative native, + guint min_args); + +void swfdec_as_native_function_set_object_type + (SwfdecAsNativeFunction *function, + GType type); + + +G_END_DECLS +#endif diff --git a/libswfdec/swfdec_as_number.c b/libswfdec/swfdec_as_number.c index 3e81829..7fff37b 100644 --- a/libswfdec/swfdec_as_number.c +++ b/libswfdec/swfdec_as_number.c @@ -26,7 +26,7 @@ #include "swfdec_as_number.h" #include "swfdec_as_context.h" #include "swfdec_as_frame.h" -#include "swfdec_as_function.h" +#include "swfdec_as_native_function.h" #include "swfdec_debug.h" G_DEFINE_TYPE (SwfdecAsNumber, swfdec_as_number, SWFDEC_TYPE_AS_OBJECT) @@ -116,7 +116,8 @@ swfdec_as_number_init_context (SwfdecAsC if (!number) return; context->Number = number; - swfdec_as_function_set_object_type (SWFDEC_AS_FUNCTION (number), SWFDEC_TYPE_AS_NUMBER); + swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (number), + SWFDEC_TYPE_AS_NUMBER); if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsNumber))) return; proto = g_object_new (SWFDEC_TYPE_AS_NUMBER, NULL); diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c index a250918..1c53e0d 100644 --- a/libswfdec/swfdec_as_object.c +++ b/libswfdec/swfdec_as_object.c @@ -24,7 +24,7 @@ #include "swfdec_as_object.h" #include "swfdec_as_context.h" #include "swfdec_as_frame.h" -#include "swfdec_as_function.h" +#include "swfdec_as_native_function.h" #include "swfdec_debug.h" @@ -472,11 +472,11 @@ swfdec_as_object_add_function (SwfdecAsO if (!native) native = swfdec_as_object_do_nothing; - function = swfdec_as_function_new_native (object->context, name, native, min_args); + function = swfdec_as_native_function_new (object->context, name, native, min_args); if (function == NULL) return NULL; if (type != 0) - swfdec_as_function_set_object_type (function, type); + swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (function), type); name = swfdec_as_context_get_string (object->context, name); SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (function)); /* FIXME: I'd like to make sure no such property exists yet */ @@ -576,15 +576,41 @@ swfdec_as_object_has_function (SwfdecAsO SwfdecAsObject * swfdec_as_object_create (SwfdecAsFunction *construct, guint n_args, SwfdecAsValue *args) { - static SwfdecAsValue val; /* ignored */ + SwfdecAsValue val; SwfdecAsObject *new; SwfdecAsContext *context; + SwfdecAsFunction *cur; + guint size; + GType type = 0; g_return_val_if_fail (SWFDEC_IS_AS_FUNCTION (construct), NULL); g_return_val_if_fail (n_args == 0 || args != NULL, NULL); context = SWFDEC_AS_OBJECT (construct)->context; - if (!swfdec_as_context_use_mem (context, construct->type_size)) { + cur = construct; + while (type == 0 && cur != NULL) { + if (SWFDEC_IS_AS_NATIVE_FUNCTION (construct)) { + SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (construct); + if (native->type_size) { + type = native->type; + size = native->type_size; + break; + } + } + swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (cur), SWFDEC_AS_STR___constructor__, &val); + if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) { + cur = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val); + if (!SWFDEC_IS_AS_FUNCTION (cur)) + cur = NULL; + } else { + cur = NULL; + } + } + if (type == 0) { + type = SWFDEC_TYPE_AS_OBJECT; + size = sizeof (SwfdecAsObject); + } + if (!swfdec_as_context_use_mem (context, size)) { SwfdecAsObject *proto; swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (construct), SWFDEC_AS_STR_prototype, &val); if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) { @@ -594,8 +620,8 @@ swfdec_as_object_create (SwfdecAsFunctio } return proto; } - new = g_object_new (construct->type, NULL); - swfdec_as_object_add (new, context, construct->type_size); + new = g_object_new (type, NULL); + swfdec_as_object_add (new, context, size); swfdec_as_object_set_constructor (new, SWFDEC_AS_OBJECT (construct)); swfdec_as_function_call (construct, new, n_args, args, &val); context->frame->construct = TRUE; diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c new file mode 100644 index 0000000..2f75150 --- /dev/null +++ b/libswfdec/swfdec_as_script_function.c @@ -0,0 +1,110 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte at gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "swfdec_as_script_function.h" +#include "swfdec_as_context.h" +#include "swfdec_as_frame.h" +#include "swfdec_as_stack.h" +#include "swfdec_debug.h" + +G_DEFINE_TYPE (SwfdecAsScriptFunction, swfdec_as_script_function, SWFDEC_TYPE_AS_FUNCTION) + +static void +swfdec_as_script_function_call (SwfdecAsFunction *function, SwfdecAsObject *thisp) +{ + SwfdecAsScriptFunction *script = SWFDEC_AS_SCRIPT_FUNCTION (function); + SwfdecAsFrame *frame; + + frame = swfdec_as_frame_new (thisp, script->script); + SWFDEC_AS_SCOPE (frame)->next = script->scope; + frame->scope = SWFDEC_AS_SCOPE (frame); +} + +static void +swfdec_as_script_function_dispose (GObject *object) +{ + SwfdecAsScriptFunction *script = SWFDEC_AS_SCRIPT_FUNCTION (object); + + if (script->script) { + swfdec_script_unref (script->script); + script->script = NULL; + } + + G_OBJECT_CLASS (swfdec_as_script_function_parent_class)->dispose (object); +} + +static void +swfdec_as_script_function_mark (SwfdecAsObject *object) +{ + SwfdecAsScriptFunction *script= SWFDEC_AS_SCRIPT_FUNCTION (object); + + if (script->scope) + swfdec_as_object_mark (SWFDEC_AS_OBJECT (script->scope)); + + SWFDEC_AS_OBJECT_CLASS (swfdec_as_script_function_parent_class)->mark (object); +} + +static void +swfdec_as_script_function_class_init (SwfdecAsScriptFunctionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass); + SwfdecAsFunctionClass *function_class = SWFDEC_AS_FUNCTION_CLASS (klass); + + object_class->dispose = swfdec_as_script_function_dispose; + + asobject_class->mark = swfdec_as_script_function_mark; + + function_class->call = swfdec_as_script_function_call; +} + +static void +swfdec_as_script_function_init (SwfdecAsScriptFunction *script_function) +{ +} + +SwfdecAsFunction * +swfdec_as_script_function_new (SwfdecAsScope *scope) +{ + SwfdecAsValue val; + SwfdecAsFunction *fun; + SwfdecAsObject *proto; + + g_return_val_if_fail (SWFDEC_IS_AS_SCOPE (scope), NULL); + + fun = swfdec_as_function_create (SWFDEC_AS_OBJECT (scope)->context, + SWFDEC_TYPE_AS_SCRIPT_FUNCTION, sizeof (SwfdecAsScriptFunction)); + if (fun == NULL) + return NULL; + proto = swfdec_as_object_new (SWFDEC_AS_OBJECT (scope)->context); + if (proto == NULL) + return NULL; + SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (fun)); + swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val); + SWFDEC_AS_VALUE_SET_OBJECT (&val, proto); + swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, &val); + SWFDEC_AS_SCRIPT_FUNCTION (fun)->scope = scope; + + return fun; +} + diff --git a/libswfdec/swfdec_as_script_function.h b/libswfdec/swfdec_as_script_function.h new file mode 100644 index 0000000..1034416 --- /dev/null +++ b/libswfdec/swfdec_as_script_function.h @@ -0,0 +1,59 @@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte at gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef _SWFDEC_AS_SCRIPT_FUNCTION_H_ +#define _SWFDEC_AS_SCRIPT_FUNCTION_H_ + +#include <libswfdec/swfdec_as_function.h> +#include <libswfdec/swfdec_as_types.h> +#include <libswfdec/swfdec_script.h> + +G_BEGIN_DECLS + +typedef struct _SwfdecAsScriptFunction SwfdecAsScriptFunction; +typedef struct _SwfdecAsScriptFunctionClass SwfdecAsScriptFunctionClass; + +#define SWFDEC_TYPE_AS_SCRIPT_FUNCTION (swfdec_as_script_function_get_type()) +#define SWFDEC_IS_AS_SCRIPT_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_SCRIPT_FUNCTION)) +#define SWFDEC_IS_AS_SCRIPT_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_SCRIPT_FUNCTION)) +#define SWFDEC_AS_SCRIPT_FUNCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_SCRIPT_FUNCTION, SwfdecAsScriptFunction)) +#define SWFDEC_AS_SCRIPT_FUNCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_SCRIPT_FUNCTION, SwfdecAsScriptFunctionClass)) +#define SWFDEC_AS_SCRIPT_FUNCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_SCRIPT_FUNCTION, SwfdecAsScriptFunctionClass)) + +/* FIXME: do two obejcts, one for scripts and one for native? */ +struct _SwfdecAsScriptFunction { + SwfdecAsFunction function; + + /* for script script_functions */ + SwfdecScript * script; /* script being executed or NULL when native */ + SwfdecAsScope * scope; /* scope this script_function was defined in or NULL */ +}; + +struct _SwfdecAsScriptFunctionClass { + SwfdecAsFunctionClass function_class; +}; + +GType swfdec_as_script_function_get_type (void); + +/* FIXME: verify what scope a script_function gets that is defined inside a With statement */ +SwfdecAsFunction * swfdec_as_script_function_new (SwfdecAsScope * scope); + + +G_END_DECLS +#endif
Seemingly Similar Threads
- Branch 'as' - libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_script_function.c
- Branch 'as' - 9 commits - libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_script_function.c
- Branch 'vivi' - 9 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c
- 12 commits - AUTHORS doc/Makefile.am doc/swfdec-docs.sgml doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_as_array.c libswfdec/swfdec_as_array.h libswfdec/swfdec_as_context.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h
- Branch 'as' - 11 commits - libswfdec/swfdec_as_array.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_function.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_number.c libswfdec/swfdec_as_object.c