[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