[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
Benjamin Otte
company at kemper.freedesktop.org
Fri May 18 08:30:11 PDT 2007
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
More information about the Swfdec
mailing list