[Swfdec] Branch 'as' - 14 commits - libswfdec-gtk/swfdec_playback_alsa.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_function.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h libswfdec/swfdec_loadertarget.c libswfdec/swfdec_net_stream.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h player/swfdec_debug_stack.c

Benjamin Otte company at kemper.freedesktop.org
Thu Apr 12 11:58:09 PDT 2007


 libswfdec-gtk/swfdec_playback_alsa.c |    3 
 libswfdec/swfdec_as_context.c        |   55 ++++++++++++---
 libswfdec/swfdec_as_context.h        |    4 +
 libswfdec/swfdec_as_frame.c          |    6 +
 libswfdec/swfdec_as_frame.h          |    6 +
 libswfdec/swfdec_as_function.c       |   65 ++++++++++++------
 libswfdec/swfdec_as_function.h       |   13 +--
 libswfdec/swfdec_as_interpret.c      |  122 +++++++++++++++++------------------
 libswfdec/swfdec_as_object.c         |   82 +++++++++++++++++++++++
 libswfdec/swfdec_as_object.h         |   24 ++++++
 libswfdec/swfdec_as_types.c          |   53 ++++++++-------
 libswfdec/swfdec_as_types.h          |   53 +++++++++------
 libswfdec/swfdec_loadertarget.c      |    3 
 libswfdec/swfdec_net_stream.c        |    2 
 libswfdec/swfdec_player.c            |    9 +-
 libswfdec/swfdec_player_internal.h   |    1 
 player/swfdec_debug_stack.c          |   12 +--
 17 files changed, 357 insertions(+), 156 deletions(-)

New commits:
diff-tree 5f393d7cbd7fadf4d9e3f49822c295f78678ff30 (from 8b0e7a337c8d41796f2c5efba1f2556f58ef2d28)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 20:50:12 2007 +0200

    add framework for AS context initialization
    
    swfdec_as_context_startup needs to be called. This populates the context with
    the default objects available in Flash.

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 9ed00ec..efcf513 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -36,6 +36,8 @@
 
 /**
  * SwfdecAsContextState
+ * @SWFDEC_AS_CONTEXT_NEW: the context is not yet initialized, 
+ *                         swfdec_as_context_startup() needs to be called.
  * @SWFDEC_AS_CONTEXT_RUNNING: the context is running normally
  * @SWFDEC_AS_CONTEXT_INTERRUPTED: the context has been interrupted by a 
  *                             debugger
@@ -384,7 +386,7 @@ start:
     goto out;
   if (frame->function && frame->function->native) {
     if (frame->argc >= frame->function->min_args) {
-      frame->function->native (context, frame->scope, frame->argc, frame->argv, frame->return_value);
+      frame->function->native (frame->scope, frame->argc, frame->argv, frame->return_value);
     }
     swfdec_as_context_return (context);
     goto start;
@@ -507,6 +509,26 @@ swfdec_as_context_trace (SwfdecAsContext
   g_signal_emit (context, signals[TRACE], 0, string);
 }
 
+/**
+ * swfdec_as_context_startup:
+ * @context: a #SwfdecAsContext
+ * @version: Flash version to use
+ *
+ * Starts up the context. This function must be called before any Actionscript
+ * is called on @context. The version is responsible for deciding which native
+ * functions and properties are available in the context.
+ **/
+void
+swfdec_as_context_startup (SwfdecAsContext *context, guint version)
+{
+  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+  g_return_if_fail (context->state == SWFDEC_AS_CONTEXT_NEW);
+
+  context->version = version;
+  swfdec_as_function_init_context (context, version);
+  context->state = SWFDEC_AS_CONTEXT_RUNNING;
+}
+
 /*** EVAL ***/
 
 char *
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index c811db4..31e6757 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -26,6 +26,7 @@
 G_BEGIN_DECLS
 
 typedef enum {
+  SWFDEC_AS_CONTEXT_NEW,
   SWFDEC_AS_CONTEXT_RUNNING,
   SWFDEC_AS_CONTEXT_INTERRUPTED,
   SWFDEC_AS_CONTEXT_ABORTED
@@ -73,6 +74,8 @@ struct _SwfdecAsContextClass {
 GType		swfdec_as_context_get_type	(void);
 
 SwfdecAsContext *swfdec_as_context_new		(void);
+void		swfdec_as_context_startup     	(SwfdecAsContext *	context,
+						 guint			version);
 
 const char *	swfdec_as_context_get_string	(SwfdecAsContext *	context,
 						 const char *		string);
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 643fed5..8f404b7 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -139,7 +139,38 @@ swfdec_as_function_call (SwfdecAsFunctio
     frame->function_name = function->name;
   } else {
     frame = swfdec_as_frame_new (thisp, function->script);
-    /* FIXME: do the preloading here */
+    SWFDEC_ERROR ("do the preloading here");
   }
 }
 
+/*** AS CODE ***/
+
+static void
+swfdec_as_function_construct (SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+
+}
+
+void
+swfdec_as_function_init_context (SwfdecAsContext *context, guint version)
+{
+  SwfdecAsObject *function, *proto;
+  SwfdecAsValue val;
+
+  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+
+  function = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
+      SWFDEC_AS_STR_Function, swfdec_as_function_construct, 0));
+  if (!function)
+    return;
+  proto = swfdec_as_object_new (context);
+  if (!proto)
+    return;
+  swfdec_as_object_root (proto);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
+  swfdec_as_object_set (function, SWFDEC_AS_STR___proto__, &val);
+  swfdec_as_object_set (function, SWFDEC_AS_STR_prototype, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, function);
+  swfdec_as_object_set (function, SWFDEC_AS_STR_constructor, &val);
+  swfdec_as_object_unroot (proto);
+}
diff --git a/libswfdec/swfdec_as_function.h b/libswfdec/swfdec_as_function.h
index 3f0cadc..260eb1f 100644
--- a/libswfdec/swfdec_as_function.h
+++ b/libswfdec/swfdec_as_function.h
@@ -67,6 +67,8 @@ void			swfdec_as_function_call		(SwfdecA
 							 SwfdecAsValue *	args,
 							 SwfdecAsValue *	return_value);
 
+void			swfdec_as_function_init_context (SwfdecAsContext *	context,
+							 guint			version);
 
 
 G_END_DECLS
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index b2a73cc..0782e45 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -100,6 +100,9 @@ const char *swfdec_as_strings[] = {
   SWFDEC_AS_CONSTANT_STRING ("object"),
   SWFDEC_AS_CONSTANT_STRING ("toString"),
   SWFDEC_AS_CONSTANT_STRING ("valueOf"),
+  SWFDEC_AS_CONSTANT_STRING ("Function"),
+  SWFDEC_AS_CONSTANT_STRING ("prototype"),
+  SWFDEC_AS_CONSTANT_STRING ("constructor"),
   /* add more here */
   NULL
 };
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index b20b2e6..96fe3b4 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -42,7 +42,7 @@ typedef struct _SwfdecAsFunction SwfdecA
 typedef struct _SwfdecAsObject SwfdecAsObject;
 typedef struct _SwfdecAsStack SwfdecAsStack;
 typedef struct _SwfdecAsValue SwfdecAsValue;
-typedef void (* SwfdecAsNative) (SwfdecAsContext *context, SwfdecAsObject *thisp, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval);
+typedef void (* SwfdecAsNative) (SwfdecAsObject *thisp, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval);
 
 /* IMPORTANT: a SwfdecAsValue memset to 0 is a valid undefined value */
 struct _SwfdecAsValue {
@@ -102,7 +102,7 @@ extern const char *swfdec_as_strings[];
 #define SWFDEC_AS_STR_CONSTANT(n) (&swfdec_as_strings[(n)][1])
 
 #define SWFDEC_AS_STR_EMPTY		SWFDEC_AS_STR_CONSTANT(0)
-#define SWFDEC_AS_STR_PROTO		SWFDEC_AS_STR_CONSTANT(1)
+#define SWFDEC_AS_STR___proto__		SWFDEC_AS_STR_CONSTANT(1)
 #define SWFDEC_AS_STR_THIS		SWFDEC_AS_STR_CONSTANT(2)
 #define SWFDEC_AS_STR_CODE		SWFDEC_AS_STR_CONSTANT(3)
 #define SWFDEC_AS_STR_LEVEL		SWFDEC_AS_STR_CONSTANT(4)
@@ -171,6 +171,9 @@ extern const char *swfdec_as_strings[];
 #define SWFDEC_AS_STR_OBJECT		SWFDEC_AS_STR_CONSTANT(67)
 #define SWFDEC_AS_STR_TOSTRING		SWFDEC_AS_STR_CONSTANT(68)
 #define SWFDEC_AS_STR_VALUEOF		SWFDEC_AS_STR_CONSTANT(69)
+#define SWFDEC_AS_STR_Function		SWFDEC_AS_STR_CONSTANT(70)
+#define SWFDEC_AS_STR_prototype		SWFDEC_AS_STR_CONSTANT(71)
+#define SWFDEC_AS_STR_constructor	SWFDEC_AS_STR_CONSTANT(72)
 
 /* all existing actions */
 typedef enum {
diff --git a/libswfdec/swfdec_loadertarget.c b/libswfdec/swfdec_loadertarget.c
index 40ad26f..480d13c 100644
--- a/libswfdec/swfdec_loadertarget.c
+++ b/libswfdec/swfdec_loadertarget.c
@@ -127,7 +127,8 @@ swfdec_loader_target_parse_default (Swfd
 	  player = swfdec_loader_target_get_player (target);
 	  g_assert (dec->width > 0);
 	  g_assert (dec->height > 0);
-	  swfdec_player_initialize (player, dec->rate, 
+	  /* FIXME: need correct version here */
+	  swfdec_player_initialize (player, 7, dec->rate, 
 	      dec->width, dec->height);
 	  if (!swfdec_loader_target_init (target)) {
 	    swfdec_loader_error_locked (loader, "Internal error");
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index fc19af2..b2e95f0 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -223,7 +223,7 @@ swfdec_net_stream_loader_target_parse (S
 	break;
       case SWFDEC_STATUS_INIT:
 	/* HACK for native flv playback */
-	swfdec_player_initialize (stream->player, 
+	swfdec_player_initialize (stream->player, 7,
 	    SWFDEC_DECODER (stream->flvdecoder)->rate, 
 	    SWFDEC_DECODER (stream->flvdecoder)->width, 
 	    SWFDEC_DECODER (stream->flvdecoder)->height);
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 3d2ca6c..7103780 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1002,15 +1002,17 @@ swfdec_player_launch (SwfdecPlayer *play
 /**
  * swfdec_player_initialize:
  * @player: a #SwfdecPlayer
+ * @version: Flash version to use
  * @rate: framerate in 256th or 0 for undefined
  * @width: width of movie
  * @height: height of movie
  *
- * Initializes the player to the given @width, @height and @rate. If the player
- * is already initialized, this function does nothing.
+ * Initializes the player to the given @version, @width, @height and @rate. If 
+ * the player is already initialized, this function does nothing.
  **/
 void
-swfdec_player_initialize (SwfdecPlayer *player, guint rate, guint width, guint height)
+swfdec_player_initialize (SwfdecPlayer *player, guint version, 
+    guint rate, guint width, guint height)
 {
   g_return_if_fail (SWFDEC_IS_PLAYER (player));
   g_return_if_fail (width > 0);
@@ -1019,6 +1021,7 @@ swfdec_player_initialize (SwfdecPlayer *
   if (swfdec_player_is_initialized (player))
     return;
   
+  swfdec_as_context_startup (SWFDEC_AS_CONTEXT (player), version);
   SWFDEC_INFO ("initializing player to size %ux%u", width, height);
   player->rate = rate;
   player->width = width;
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index c84805b..a6b0238 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -101,6 +101,7 @@ struct _SwfdecPlayerClass
 };
 
 void		swfdec_player_initialize	(SwfdecPlayer *		player,
+						 guint			version,
 						 guint			rate,
 						 guint			width,
 						 guint			height);
diff-tree 8b0e7a337c8d41796f2c5efba1f2556f58ef2d28 (from 0004e27772fdad415f1217f113ab64400af72625)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 20:48:24 2007 +0200

    add workaround for broken ALSA headers

diff --git a/libswfdec-gtk/swfdec_playback_alsa.c b/libswfdec-gtk/swfdec_playback_alsa.c
index ee4da3e..f5f1836 100644
--- a/libswfdec-gtk/swfdec_playback_alsa.c
+++ b/libswfdec-gtk/swfdec_playback_alsa.c
@@ -21,6 +21,9 @@
 #include "config.h"
 #endif
 
+/* HACK: ALSA headers don't compile with C99 otherwise */
+#define __need_timespec 1
+
 #include <alsa/asoundlib.h>
 #include "swfdec_playback.h"
 
diff-tree 0004e27772fdad415f1217f113ab64400af72625 (from cb15af072feee4d0ea3672d283597e1b4ccfefe1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 20:47:51 2007 +0200

    use new variables types

diff --git a/player/swfdec_debug_stack.c b/player/swfdec_debug_stack.c
index cd42487..591d53c 100644
--- a/player/swfdec_debug_stack.c
+++ b/player/swfdec_debug_stack.c
@@ -39,17 +39,17 @@ static const char *
 swfdec_get_value_type (SwfdecAsContext *cx, SwfdecAsValue *value)
 {
   switch (value->type) {
-    case SWFDEC_TYPE_AS_UNDEFINED:
+    case SWFDEC_AS_TYPE_UNDEFINED:
       return "undefined";
-    case SWFDEC_TYPE_AS_NULL:
+    case SWFDEC_AS_TYPE_NULL:
       return "null";
-    case SWFDEC_TYPE_AS_NUMBER:
+    case SWFDEC_AS_TYPE_NUMBER:
       return "Number";
-    case SWFDEC_TYPE_AS_BOOLEAN:
+    case SWFDEC_AS_TYPE_BOOLEAN:
       return "Boolean";
-    case SWFDEC_TYPE_AS_STRING:
+    case SWFDEC_AS_TYPE_STRING:
       return "String";
-    case SWFDEC_TYPE_AS_ASOBJECT:
+    case SWFDEC_AS_TYPE_OBJECT:
       /* FIXME: improve */
       return "Object";
     default:
diff-tree cb15af072feee4d0ea3672d283597e1b4ccfefe1 (from ba06192bc917398202563f5c9a00d13ba3aa456f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 19:15:17 2007 +0200

    That return_if_fail was wrong

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index a064716..ff9abbd 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -310,7 +310,7 @@ swfdec_as_object_set_variable_flags (Swf
   SwfdecAsVariable *var;
 
   g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
-  g_return_if_fail ((flags & SWFDEC_AS_VARIABLE_NATIVE) != 0);
+  g_return_if_fail ((flags & SWFDEC_AS_VARIABLE_NATIVE) == 0);
 
   var = swfdec_as_object_lookup (object, variable, FALSE);
   g_return_if_fail (var != NULL);
@@ -332,7 +332,7 @@ swfdec_as_object_unset_variable_flags (S
   SwfdecAsVariable *var;
 
   g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
-  g_return_if_fail ((flags & SWFDEC_AS_VARIABLE_NATIVE) != 0);
+  g_return_if_fail ((flags & SWFDEC_AS_VARIABLE_NATIVE) == 0);
 
   var = swfdec_as_object_lookup (object, variable, FALSE);
   g_return_if_fail (var != NULL);
diff-tree ba06192bc917398202563f5c9a00d13ba3aa456f (from b865d1b41ac11300180168d3d5baf4d48dae6dab)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 18:49:19 2007 +0200

    add functions to set a variable's flags
    
    + add a function to add native functions.
    + rename SwfdecAsNativeCall to SwfdecAsNative

diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 0e52e7c..643fed5 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -90,7 +90,7 @@ swfdec_as_function_new (SwfdecAsFrame *s
 }
 
 SwfdecAsFunction *
-swfdec_as_function_new_native (SwfdecAsContext *context, SwfdecAsNativeCall native,
+swfdec_as_function_new_native (SwfdecAsContext *context, SwfdecAsNative native,
     guint min_args)
 {
   SwfdecAsFunction *fun;
diff --git a/libswfdec/swfdec_as_function.h b/libswfdec/swfdec_as_function.h
index 59df2ac..3f0cadc 100644
--- a/libswfdec/swfdec_as_function.h
+++ b/libswfdec/swfdec_as_function.h
@@ -40,7 +40,7 @@ struct _SwfdecAsFunction {
   SwfdecAsObject	object;
 
   /* for native functions */
-  SwfdecAsNativeCall	native;		/* native call or NULL when script */
+  SwfdecAsNative	native;		/* native call or NULL when script */
   guint			min_args;	/* minimum number of required arguments */
   char *		name;		/* function name */
 
@@ -58,7 +58,7 @@ GType			swfdec_as_function_get_type	(voi
 SwfdecAsFunction *	swfdec_as_function_new		(SwfdecAsFrame *	scope,
 							 SwfdecScript *		script);
 SwfdecAsFunction *	swfdec_as_function_new_native	(SwfdecAsContext *	context,
-							 SwfdecAsNativeCall	native,
+							 SwfdecAsNative		native,
 							 guint			min_args);
 
 void			swfdec_as_function_call		(SwfdecAsFunction *	function,
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 5cda61b..a064716 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -296,6 +296,87 @@ swfdec_as_object_find_variable (SwfdecAs
 }
 
 /**
+ * swfdec_as_object_set_variable_flags:
+ * @object: a #SwfdecAsObject
+ * @variable: the variable to modify
+ * @flags: flags to set
+ *
+ * Sets the given flags for the given variable.
+ **/
+void
+swfdec_as_object_set_variable_flags (SwfdecAsObject *object, 
+    const SwfdecAsValue *variable, SwfdecAsVariableFlag flags)
+{
+  SwfdecAsVariable *var;
+
+  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
+  g_return_if_fail ((flags & SWFDEC_AS_VARIABLE_NATIVE) != 0);
+
+  var = swfdec_as_object_lookup (object, variable, FALSE);
+  g_return_if_fail (var != NULL);
+  var->flags |= flags;
+}
+
+/**
+ * swfdec_as_object_unset_variable_flags:
+ * @object: a #SwfdecAsObject
+ * @variable: the variable to modify
+ * @flags: flags to unset
+ *
+ * Unsets the given flags for the given variable.
+ **/
+void
+swfdec_as_object_unset_variable_flags (SwfdecAsObject *object,
+    const SwfdecAsValue *variable, SwfdecAsVariableFlag flags)
+{
+  SwfdecAsVariable *var;
+
+  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
+  g_return_if_fail ((flags & SWFDEC_AS_VARIABLE_NATIVE) != 0);
+
+  var = swfdec_as_object_lookup (object, variable, FALSE);
+  g_return_if_fail (var != NULL);
+  var->flags &= ~flags;
+}
+
+/*** SIMPLIFICATIONS ***/
+
+/**
+ * swfdec_as_object_add_function:
+ * @object: a #SwfdecAsObject
+ * @name: name of the function. The string does not have to be 
+ *        garbage-collected.
+ * @native: a native function
+ * @min_args: minimum number of arguments to pass to @native
+ *
+ * Adds @native as a variable named @name to @object. The newly added variable
+ * will not be enumerated.
+ *
+ * Returns: the newly created #SwfdecAsFunction or %NULL on error.
+ **/
+SwfdecAsFunction *
+swfdec_as_object_add_function (SwfdecAsObject *object, const char *name, 
+    SwfdecAsNative native, guint min_args)
+{
+  SwfdecAsFunction *function;
+  SwfdecAsValue val;
+
+  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (native != NULL, NULL);
+
+  function = swfdec_as_function_new_native (object->context, native, min_args);
+  if (function == NULL)
+    return NULL;
+  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 */
+  swfdec_as_object_set (object, name, &val);
+  swfdec_as_object_set_flags (object, name, SWFDEC_AS_VARIABLE_DONT_ENUM);
+  return function;
+}
+
+/**
  * swfdec_as_object_run:
  * @object: a #SwfdecAsObject
  * @script: script to execute
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 0876bbb..cdd98e8 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -110,6 +110,14 @@ void		swfdec_as_object_delete_variable(S
 						 const SwfdecAsValue *	variable);
 SwfdecAsObject *swfdec_as_object_find_variable	(SwfdecAsObject *	object,
 						 const SwfdecAsValue *	variable);
+void		swfdec_as_object_set_variable_flags
+						(SwfdecAsObject *       object,
+						 const SwfdecAsValue *	variable,
+						 SwfdecAsVariableFlag	flags);
+void		swfdec_as_object_unset_variable_flags
+						(SwfdecAsObject *       object,
+						 const SwfdecAsValue *	variable,
+						 SwfdecAsVariableFlag	flags);
 
 /* shortcuts, you probably don't want to bind them */
 #define swfdec_as_object_set(object, name, value) G_STMT_START { \
@@ -122,6 +130,21 @@ SwfdecAsObject *swfdec_as_object_find_va
   SWFDEC_AS_VALUE_SET_STRING (&__variable, (name)); \
   swfdec_as_object_get_variable ((object), &__variable, (value)); \
 }G_STMT_END
+#define swfdec_as_object_set_flags(object, name, flags) G_STMT_START { \
+  SwfdecAsValue __variable; \
+  SWFDEC_AS_VALUE_SET_STRING (&__variable, (name)); \
+  swfdec_as_object_set_variable_flags ((object), &__variable, (flags)); \
+}G_STMT_END
+#define swfdec_as_object_unset_flags(object, name, flags) G_STMT_START { \
+  SwfdecAsValue __variable; \
+  SWFDEC_AS_VALUE_SET_STRING (&__variable, (name)); \
+  swfdec_as_object_set_variable_flags ((object), &__variable, (flags)); \
+}G_STMT_END
+
+SwfdecAsFunction *swfdec_as_object_add_function	(SwfdecAsObject *	object,
+						 const char *		name,
+						 SwfdecAsNative		native,
+						 guint			min_args);
 
 void		swfdec_as_object_run		(SwfdecAsObject *       object,
 						 SwfdecScript *		script);
@@ -132,6 +155,7 @@ void		swfdec_as_object_call		(SwfdecAsOb
 						 guint			argc,
 						 SwfdecAsValue *	argv,
 						 SwfdecAsValue *	return_value);
+						 
 
 G_END_DECLS
 #endif
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index fbea00c..b20b2e6 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -42,7 +42,7 @@ typedef struct _SwfdecAsFunction SwfdecA
 typedef struct _SwfdecAsObject SwfdecAsObject;
 typedef struct _SwfdecAsStack SwfdecAsStack;
 typedef struct _SwfdecAsValue SwfdecAsValue;
-typedef void (* SwfdecAsNativeCall) (SwfdecAsContext *context, SwfdecAsObject *thisp, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval);
+typedef void (* SwfdecAsNative) (SwfdecAsContext *context, SwfdecAsObject *thisp, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval);
 
 /* IMPORTANT: a SwfdecAsValue memset to 0 is a valid undefined value */
 struct _SwfdecAsValue {
diff-tree b865d1b41ac11300180168d3d5baf4d48dae6dab (from a5f595aed2ba44c1f93e1f3cba64dae739838aa9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 16:40:45 2007 +0200

    assert that no OBJECT value ever gets set to NULL

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 84ea82f..9ed00ec 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -614,19 +614,18 @@ swfdec_as_context_eval_internal (SwfdecA
   } else {
     varlist = g_strsplit (str, ".", -1);
   }
-  SWFDEC_AS_VALUE_SET_OBJECT (&cur, obj); /* FIXME: can be NULL here */
   for (i = 0; varlist[i] != NULL; i++) {
     const char *dot = swfdec_as_context_get_string (cx, varlist[i]);
-    if (!SWFDEC_AS_VALUE_IS_OBJECT (&cur)) {
-      SWFDEC_AS_VALUE_SET_UNDEFINED (&cur);
-      break;
-    }
-    obj = SWFDEC_AS_VALUE_GET_OBJECT (&cur);
     if (varlist[i+1] != NULL) {
       swfdec_as_context_eval_get_property (cx, obj, dot, &cur);
+      if (!SWFDEC_AS_VALUE_IS_OBJECT (&cur)) {
+	SWFDEC_AS_VALUE_SET_UNDEFINED (&cur);
+	break;
+      }
+      obj = SWFDEC_AS_VALUE_GET_OBJECT (&cur);
     } else {
       if (set) {
-	swfdec_as_context_eval_set_property (cx, obj, dot, &cur);
+	swfdec_as_context_eval_set_property (cx, obj, dot, val);
       } else {
 	swfdec_as_context_eval_get_property (cx, obj, dot, &cur);
       }
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 823680f..9fca9af 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2245,7 +2245,7 @@ const SwfdecActionSpec swfdec_as_actions
   [0x83] = { "GetURL", swfdec_action_print_get_url, 0, 0, { swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url } },
 #endif
   /* version 5 */
-  [0x87] = { "StoreRegister", swfdec_action_print_store_register, 1, 1, { NULL, NULL, swfdec_action_store_register, swfdec_action_store_register, swfdec_action_store_register } },
+  [SWFDEC_AS_ACTION_STORE_REGISTER] = { "StoreRegister", swfdec_action_print_store_register, 1, 1, { NULL, NULL, swfdec_action_store_register, swfdec_action_store_register, swfdec_action_store_register } },
   [SWFDEC_AS_ACTION_CONSTANT_POOL] = { "ConstantPool", swfdec_action_print_constant_pool, 0, 0, { NULL, NULL, swfdec_action_constant_pool, swfdec_action_constant_pool, swfdec_action_constant_pool } },
   /* version 3 */
   [SWFDEC_AS_ACTION_WAIT_FOR_FRAME] = { "WaitForFrame", swfdec_action_print_wait_for_frame, 0, 0, { swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame } },
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index e96f86c..fbea00c 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -91,6 +91,7 @@ struct _SwfdecAsValue {
 #define SWFDEC_AS_VALUE_GET_OBJECT(val) ((val)->value.object)
 #define SWFDEC_AS_VALUE_SET_OBJECT(val,o) G_STMT_START { \
   SwfdecAsValue *__val = (val); \
+  g_assert (o != NULL); \
   (__val)->type = SWFDEC_AS_TYPE_OBJECT; \
   (__val)->value.object = o; \
 } G_STMT_END
diff-tree a5f595aed2ba44c1f93e1f3cba64dae739838aa9 (from ca116d0900fb05f19d6d32309e863dee0c7fb12d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 16:16:28 2007 +0200

    rename the value types and make them an enum

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 70a5920..823680f 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1062,20 +1062,20 @@ swfdec_action_equals2 (SwfdecAsContext *
   rtype = rval->type;
   if (ltype == rtype) {
     switch (ltype) {
-      case SWFDEC_TYPE_AS_UNDEFINED:
-      case SWFDEC_TYPE_AS_NULL:
+      case SWFDEC_AS_TYPE_UNDEFINED:
+      case SWFDEC_AS_TYPE_NULL:
 	cond = TRUE;
 	break;
-      case SWFDEC_TYPE_AS_BOOLEAN:
+      case SWFDEC_AS_TYPE_BOOLEAN:
 	cond = SWFDEC_AS_VALUE_GET_BOOLEAN (lval) == SWFDEC_AS_VALUE_GET_BOOLEAN (rval);
 	break;
-      case SWFDEC_TYPE_AS_NUMBER:
+      case SWFDEC_AS_TYPE_NUMBER:
 	cond = SWFDEC_AS_VALUE_GET_NUMBER (lval) == SWFDEC_AS_VALUE_GET_NUMBER (rval);
 	break;
-      case SWFDEC_TYPE_AS_STRING:
+      case SWFDEC_AS_TYPE_STRING:
 	cond = SWFDEC_AS_VALUE_GET_STRING (lval) == SWFDEC_AS_VALUE_GET_STRING (rval);
 	break;
-      case SWFDEC_TYPE_AS_ASOBJECT:
+      case SWFDEC_AS_TYPE_OBJECT:
 	cond = SWFDEC_AS_VALUE_GET_OBJECT (lval) == SWFDEC_AS_VALUE_GET_OBJECT (rval);
 	break;
       default:
@@ -1084,9 +1084,9 @@ swfdec_action_equals2 (SwfdecAsContext *
 	break;
     }
   } else {
-    if (ltype == SWFDEC_TYPE_AS_UNDEFINED || ltype == SWFDEC_TYPE_AS_NULL) {
-      cond = (rtype == SWFDEC_TYPE_AS_UNDEFINED || rtype == SWFDEC_TYPE_AS_NULL);
-    } else if (rtype == SWFDEC_TYPE_AS_UNDEFINED || rtype == SWFDEC_TYPE_AS_NULL) {
+    if (ltype == SWFDEC_AS_TYPE_UNDEFINED || ltype == SWFDEC_AS_TYPE_NULL) {
+      cond = (rtype == SWFDEC_AS_TYPE_UNDEFINED || rtype == SWFDEC_AS_TYPE_NULL);
+    } else if (rtype == SWFDEC_AS_TYPE_UNDEFINED || rtype == SWFDEC_AS_TYPE_NULL) {
       cond = FALSE;
     } else {
       SWFDEC_WARNING ("FIXME: test equality operations between non-equal types");
@@ -1719,22 +1719,22 @@ swfdec_action_type_of (SwfdecAsContext *
 
   val = swfdec_as_stack_peek (cx->frame->stack, 1);
   switch (val->type) {
-    case SWFDEC_TYPE_AS_NUMBER:
+    case SWFDEC_AS_TYPE_NUMBER:
       type = SWFDEC_AS_STR_NUMBER;
       break;
-    case SWFDEC_TYPE_AS_BOOLEAN:
+    case SWFDEC_AS_TYPE_BOOLEAN:
       type = SWFDEC_AS_STR_BOOLEAN;
       break;
-    case SWFDEC_TYPE_AS_STRING:
+    case SWFDEC_AS_TYPE_STRING:
       type = SWFDEC_AS_STR_STRING;
       break;
-    case SWFDEC_TYPE_AS_UNDEFINED:
+    case SWFDEC_AS_TYPE_UNDEFINED:
       type = SWFDEC_AS_STR_UNDEFINED;
       break;
-    case SWFDEC_TYPE_AS_NULL:
+    case SWFDEC_AS_TYPE_NULL:
       type = SWFDEC_AS_STR_NULL;
       break;
-    case SWFDEC_TYPE_AS_ASOBJECT:
+    case SWFDEC_AS_TYPE_OBJECT:
       {
 	SwfdecAsObject *obj = SWFDEC_AS_VALUE_GET_OBJECT (val);
 	if (SWFDEC_IS_MOVIE (obj)) {
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 889fceb..b2a73cc 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -121,25 +121,25 @@ swfdec_as_value_to_string (SwfdecAsConte
   g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), SWFDEC_AS_STR_EMPTY);
 
   switch (value->type) {
-    case SWFDEC_TYPE_AS_STRING:
+    case SWFDEC_AS_TYPE_STRING:
       return SWFDEC_AS_VALUE_GET_STRING (value);
-    case SWFDEC_TYPE_AS_UNDEFINED:
+    case SWFDEC_AS_TYPE_UNDEFINED:
       if (context->version > 6)
 	return SWFDEC_AS_STR_UNDEFINED;
       else
 	return SWFDEC_AS_STR_EMPTY;
-    case SWFDEC_TYPE_AS_BOOLEAN:
+    case SWFDEC_AS_TYPE_BOOLEAN:
       return SWFDEC_AS_VALUE_GET_BOOLEAN (value) ? SWFDEC_AS_STR_TRUE : SWFDEC_AS_STR_FALSE;
-    case SWFDEC_TYPE_AS_NULL:
+    case SWFDEC_AS_TYPE_NULL:
       return SWFDEC_AS_STR_NULL;
-    case SWFDEC_TYPE_AS_NUMBER:
+    case SWFDEC_AS_TYPE_NUMBER:
       {
 	char *s = g_strdup_printf ("%g", SWFDEC_AS_VALUE_GET_NUMBER (value));
 	const char *ret = swfdec_as_context_get_string (context, s);
 	g_free (s);
 	return ret;
       }
-    case SWFDEC_TYPE_AS_ASOBJECT:
+    case SWFDEC_AS_TYPE_OBJECT:
       {
 	SwfdecAsValue ret;
 	swfdec_as_object_call (SWFDEC_AS_VALUE_GET_OBJECT (value), SWFDEC_AS_STR_TOSTRING,
@@ -173,7 +173,7 @@ swfdec_as_value_to_printable (SwfdecAsCo
   g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), SWFDEC_AS_STR_EMPTY);
 
   switch (value->type) {
-    case SWFDEC_TYPE_AS_UNDEFINED:
+    case SWFDEC_AS_TYPE_UNDEFINED:
       return SWFDEC_AS_STR_UNDEFINED;
     default:
       break;
@@ -188,14 +188,14 @@ swfdec_as_value_to_number (SwfdecAsConte
   g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), 0.0);
 
   switch (value->type) {
-    case SWFDEC_TYPE_AS_UNDEFINED:
-    case SWFDEC_TYPE_AS_NULL:
+    case SWFDEC_AS_TYPE_UNDEFINED:
+    case SWFDEC_AS_TYPE_NULL:
       return (context->version >= 7) ? NAN : 0.0;
-    case SWFDEC_TYPE_AS_BOOLEAN:
+    case SWFDEC_AS_TYPE_BOOLEAN:
       return SWFDEC_AS_VALUE_GET_BOOLEAN (value) ? 1 : 0;
-    case SWFDEC_TYPE_AS_NUMBER:
+    case SWFDEC_AS_TYPE_NUMBER:
       return SWFDEC_AS_VALUE_GET_NUMBER (value);
-    case SWFDEC_TYPE_AS_STRING:
+    case SWFDEC_AS_TYPE_STRING:
       {
 	char *end;
 	double d = g_ascii_strtod (SWFDEC_AS_VALUE_GET_STRING (value), &end);
@@ -204,7 +204,7 @@ swfdec_as_value_to_number (SwfdecAsConte
 	else
 	  return NAN;
       }
-    case SWFDEC_TYPE_AS_ASOBJECT:
+    case SWFDEC_AS_TYPE_OBJECT:
       {
 	SwfdecAsValue ret;
 	swfdec_as_object_call (SWFDEC_AS_VALUE_GET_OBJECT (value), SWFDEC_AS_STR_VALUEOF,
@@ -247,15 +247,15 @@ swfdec_as_value_to_object (SwfdecAsConte
   g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), NULL);
 
   switch (value->type) {
-    case SWFDEC_TYPE_AS_UNDEFINED:
-    case SWFDEC_TYPE_AS_NULL:
+    case SWFDEC_AS_TYPE_UNDEFINED:
+    case SWFDEC_AS_TYPE_NULL:
       return NULL;
-    case SWFDEC_TYPE_AS_BOOLEAN:
-    case SWFDEC_TYPE_AS_NUMBER:
-    case SWFDEC_TYPE_AS_STRING:
+    case SWFDEC_AS_TYPE_BOOLEAN:
+    case SWFDEC_AS_TYPE_NUMBER:
+    case SWFDEC_AS_TYPE_STRING:
       SWFDEC_ERROR ("FIXME: implement conversion to object");
       return NULL;
-    case SWFDEC_TYPE_AS_ASOBJECT:
+    case SWFDEC_AS_TYPE_OBJECT:
       return SWFDEC_AS_VALUE_GET_OBJECT (value);
     default:
       g_assert_not_reached ();
@@ -281,24 +281,24 @@ swfdec_as_value_to_boolean (SwfdecAsCont
 
   /* FIXME: what do we do when called in flash 4? */
   switch (value->type) {
-    case SWFDEC_TYPE_AS_UNDEFINED:
-    case SWFDEC_TYPE_AS_NULL:
+    case SWFDEC_AS_TYPE_UNDEFINED:
+    case SWFDEC_AS_TYPE_NULL:
       return FALSE;
-    case SWFDEC_TYPE_AS_BOOLEAN:
+    case SWFDEC_AS_TYPE_BOOLEAN:
       return SWFDEC_AS_VALUE_GET_BOOLEAN (value);
-    case SWFDEC_TYPE_AS_NUMBER:
+    case SWFDEC_AS_TYPE_NUMBER:
       {
 	double d = SWFDEC_AS_VALUE_GET_NUMBER (value);
 	return d != 0.0 && !isnan (d);
       }
-    case SWFDEC_TYPE_AS_STRING:
+    case SWFDEC_AS_TYPE_STRING:
       if (context->version <= 6) {
 	double d = swfdec_as_value_to_number (context, value);
 	return d != 0.0 && !isnan (d);
       } else {
 	return SWFDEC_AS_VALUE_GET_STRING (value) != SWFDEC_AS_STR_EMPTY;
       }
-    case SWFDEC_TYPE_AS_ASOBJECT:
+    case SWFDEC_AS_TYPE_OBJECT:
       return TRUE;
     default:
       g_assert_not_reached ();
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 0315aa4..e96f86c 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -25,15 +25,16 @@
 G_BEGIN_DECLS
 
 /* fundamental types */
-#define SWFDEC_TYPE_AS_UNDEFINED (0)
-#define SWFDEC_TYPE_AS_BOOLEAN	(1)
-/* #define SWFDEC_AS_INT	(2)  not defined yet, might be useful as an optimization */
-#define SWFDEC_TYPE_AS_NUMBER	(3)
-#define SWFDEC_TYPE_AS_STRING	(4)
-#define SWFDEC_TYPE_AS_NULL	(5)
-#define SWFDEC_TYPE_AS_ASOBJECT	(6)
+typedef enum {
+  SWFDEC_AS_TYPE_UNDEFINED = 0,
+  SWFDEC_AS_TYPE_BOOLEAN,
+  SWFDEC_AS_TYPE_INT, /* unimplemented, but reserved if someone wants it */
+  SWFDEC_AS_TYPE_NUMBER,
+  SWFDEC_AS_TYPE_STRING,
+  SWFDEC_AS_TYPE_NULL,
+  SWFDEC_AS_TYPE_OBJECT
+} SwfdecAsType;
 
-typedef guint8 SwfdecAsType;
 typedef struct _SwfdecAsArray SwfdecAsArray;
 typedef struct _SwfdecAsContext SwfdecAsContext;
 typedef struct _SwfdecAsFrame SwfdecAsFrame;
@@ -56,41 +57,41 @@ struct _SwfdecAsValue {
 
 #define SWFDEC_IS_AS_VALUE(val) ((val)->type <= SWFDEC_TYPE_AS_OBJECT)
 
-#define SWFDEC_AS_VALUE_IS_UNDEFINED(val) ((val)->type == SWFDEC_TYPE_AS_UNDEFINED)
-#define SWFDEC_AS_VALUE_SET_UNDEFINED(val) (val)->type = SWFDEC_TYPE_AS_UNDEFINED
+#define SWFDEC_AS_VALUE_IS_UNDEFINED(val) ((val)->type == SWFDEC_AS_TYPE_UNDEFINED)
+#define SWFDEC_AS_VALUE_SET_UNDEFINED(val) (val)->type = SWFDEC_AS_TYPE_UNDEFINED
 
-#define SWFDEC_AS_VALUE_IS_BOOLEAN(val) ((val)->type == SWFDEC_TYPE_AS_BOOLEAN)
+#define SWFDEC_AS_VALUE_IS_BOOLEAN(val) ((val)->type == SWFDEC_AS_TYPE_BOOLEAN)
 #define SWFDEC_AS_VALUE_GET_BOOLEAN(val) ((val)->value.boolean)
 #define SWFDEC_AS_VALUE_SET_BOOLEAN(val,b) G_STMT_START { \
   SwfdecAsValue *__val = (val); \
-  (__val)->type = SWFDEC_TYPE_AS_BOOLEAN; \
+  (__val)->type = SWFDEC_AS_TYPE_BOOLEAN; \
   (__val)->value.boolean = b; \
 } G_STMT_END
 
-#define SWFDEC_AS_VALUE_IS_NUMBER(val) ((val)->type == SWFDEC_TYPE_AS_NUMBER)
+#define SWFDEC_AS_VALUE_IS_NUMBER(val) ((val)->type == SWFDEC_AS_TYPE_NUMBER)
 #define SWFDEC_AS_VALUE_GET_NUMBER(val) ((val)->value.number)
 #define SWFDEC_AS_VALUE_SET_NUMBER(val,d) G_STMT_START { \
   SwfdecAsValue *__val = (val); \
-  (__val)->type = SWFDEC_TYPE_AS_NUMBER; \
+  (__val)->type = SWFDEC_AS_TYPE_NUMBER; \
   (__val)->value.number = d; \
 } G_STMT_END
 
-#define SWFDEC_AS_VALUE_IS_STRING(val) ((val)->type == SWFDEC_TYPE_AS_STRING)
+#define SWFDEC_AS_VALUE_IS_STRING(val) ((val)->type == SWFDEC_AS_TYPE_STRING)
 #define SWFDEC_AS_VALUE_GET_STRING(val) ((val)->value.string)
 #define SWFDEC_AS_VALUE_SET_STRING(val,s) G_STMT_START { \
   SwfdecAsValue *__val = (val); \
-  (__val)->type = SWFDEC_TYPE_AS_STRING; \
+  (__val)->type = SWFDEC_AS_TYPE_STRING; \
   (__val)->value.string = s; \
 } G_STMT_END
 
-#define SWFDEC_AS_VALUE_IS_NULL(val) ((val)->type == SWFDEC_TYPE_AS_NULL)
-#define SWFDEC_AS_VALUE_SET_NULL(val) (val)->type = SWFDEC_TYPE_AS_NULL
+#define SWFDEC_AS_VALUE_IS_NULL(val) ((val)->type == SWFDEC_AS_TYPE_NULL)
+#define SWFDEC_AS_VALUE_SET_NULL(val) (val)->type = SWFDEC_AS_TYPE_NULL
 
-#define SWFDEC_AS_VALUE_IS_OBJECT(val) ((val)->type == SWFDEC_TYPE_AS_ASOBJECT)
+#define SWFDEC_AS_VALUE_IS_OBJECT(val) ((val)->type == SWFDEC_AS_TYPE_OBJECT)
 #define SWFDEC_AS_VALUE_GET_OBJECT(val) ((val)->value.object)
 #define SWFDEC_AS_VALUE_SET_OBJECT(val,o) G_STMT_START { \
   SwfdecAsValue *__val = (val); \
-  (__val)->type = SWFDEC_TYPE_AS_ASOBJECT; \
+  (__val)->type = SWFDEC_AS_TYPE_OBJECT; \
   (__val)->value.object = o; \
 } G_STMT_END
 
diff-tree ca116d0900fb05f19d6d32309e863dee0c7fb12d (from 900760a97bf89329ee329c7f5566409c9a094c27)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 16:08:31 2007 +0200

    implement StoreRegister

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 6925052..70a5920 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1633,22 +1633,23 @@ swfdec_action_delete2 (SwfdecAsContext *
     return JS_TRUE;
   return JS_DeleteProperty (cx, pobj, name);
 }
+#endif
 
 static void
 swfdec_action_store_register (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
   if (len != 1) {
     SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len);
-    return JS_FALSE;
+    return;
   }
   if (!swfdec_action_has_register (cx, *data)) {
     SWFDEC_ERROR ("Cannot store into register %u, not enough registers", (guint) *data);
-    return JS_FALSE;
+    return;
   }
-  cx->fp->vars[*data] = cx->fp->sp[-1];
-  return JS_TRUE;
+  cx->frame->registers[*data] = *swfdec_as_stack_peek (cx->frame->stack, 1);
 }
 
+#if 0
 static void
 swfdec_action_modulo_5 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
@@ -1839,7 +1840,6 @@ swfdec_action_logical (SwfdecAsContext *
 
 /*** PRINT FUNCTIONS ***/
 
-#if 0
 static char *
 swfdec_action_print_store_register (guint action, const guint8 *data, guint len)
 {
@@ -1849,7 +1849,6 @@ swfdec_action_print_store_register (guin
   }
   return g_strdup_printf ("StoreRegister %u", (guint) *data);
 }
-#endif
 
 static char *
 swfdec_action_print_set_target (guint action, const guint8 *data, guint len)
@@ -2244,9 +2243,9 @@ const SwfdecActionSpec swfdec_as_actions
   [SWFDEC_AS_ACTION_GOTO_FRAME] = { "GotoFrame", swfdec_action_print_goto_frame, 0, 0, { swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame } },
 #if 0
   [0x83] = { "GetURL", swfdec_action_print_get_url, 0, 0, { swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url } },
+#endif
   /* version 5 */
   [0x87] = { "StoreRegister", swfdec_action_print_store_register, 1, 1, { NULL, NULL, swfdec_action_store_register, swfdec_action_store_register, swfdec_action_store_register } },
-#endif
   [SWFDEC_AS_ACTION_CONSTANT_POOL] = { "ConstantPool", swfdec_action_print_constant_pool, 0, 0, { NULL, NULL, swfdec_action_constant_pool, swfdec_action_constant_pool, swfdec_action_constant_pool } },
   /* version 3 */
   [SWFDEC_AS_ACTION_WAIT_FOR_FRAME] = { "WaitForFrame", swfdec_action_print_wait_for_frame, 0, 0, { swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame } },
diff-tree 900760a97bf89329ee329c7f5566409c9a094c27 (from 8d210d194935952d396460abaf0cc2718cc07822)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 16:05:06 2007 +0200

    implement Return

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 7abef77..6925052 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1590,18 +1590,16 @@ swfdec_action_define_local2 (SwfdecAsCon
   cx->fp->sp--;
   return JS_TRUE;
 }
+#endif
 
 static void
 swfdec_action_return (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
-  SwfdecScript *script = cx->fp->swf;
-
-  cx->fp->rval = cx->fp->sp[-1];
-  cx->fp->pc = script->buffer->data + script->buffer->length;
-  cx->fp->sp--;
-  return JS_TRUE;
+  cx->frame->return_value = swfdec_as_stack_pop (cx->frame->stack);
+  swfdec_as_context_return (cx);
 }
 
+#if 0
 static void
 swfdec_action_delete (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
@@ -2195,8 +2193,8 @@ const SwfdecActionSpec swfdec_as_actions
   [0x3c] = { "DefineLocal", NULL, 2, 0, { NULL, NULL, swfdec_action_define_local, swfdec_action_define_local, swfdec_action_define_local } },
 #endif
   [SWFDEC_AS_ACTION_CALL_FUNCTION] = { "CallFunction", NULL, -1, 1, { NULL, NULL, swfdec_action_call_function, swfdec_action_call_function, swfdec_action_call_function } },
-#if 0
   [0x3e] = { "Return", NULL, 1, 0, { NULL, NULL, swfdec_action_return, swfdec_action_return, swfdec_action_return } },
+#if 0
   [0x3f] = { "Modulo", NULL, 2, 1, { NULL, NULL, swfdec_action_modulo_5, swfdec_action_modulo_5, swfdec_action_modulo_7 } },
   [0x40] = { "NewObject", NULL, -1, 1, { NULL, NULL, swfdec_action_new_object, swfdec_action_new_object, swfdec_action_new_object } },
   [0x41] = { "DefineLocal2", NULL, 1, 0, { NULL, NULL, swfdec_action_define_local2, swfdec_action_define_local2, swfdec_action_define_local2 } },
diff-tree 8d210d194935952d396460abaf0cc2718cc07822 (from 1c970914da071b97223cbe955a076fc31a6d458d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 16:03:28 2007 +0200

    uncomment the unimplemented actions

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 5ba5fb2..7abef77 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2134,8 +2134,8 @@ const SwfdecActionSpec swfdec_as_actions
   [SWFDEC_AS_ACTION_PREVIOUS_FRAME] = { "PreviousFrame", NULL, 0, 0, { swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame } },
   [SWFDEC_AS_ACTION_PLAY] = { "Play", NULL, 0, 0, { swfdec_action_play, swfdec_action_play, swfdec_action_play, swfdec_action_play, swfdec_action_play } },
   [SWFDEC_AS_ACTION_STOP] = { "Stop", NULL, 0, 0, { swfdec_action_stop, swfdec_action_stop, swfdec_action_stop, swfdec_action_stop, swfdec_action_stop } },
+  [SWFDEC_AS_ACTION_TOGGLE_QUALITY] = { "ToggleQuality", NULL },
 #if 0
-  [0x08] = { "ToggleQuality", NULL },
   [0x09] = { "StopSounds", NULL, 0, 0, { swfdec_action_stop_sounds, swfdec_action_stop_sounds, swfdec_action_stop_sounds, swfdec_action_stop_sounds, swfdec_action_stop_sounds } },
 #endif
   /* version 4 */
@@ -2150,11 +2150,9 @@ const SwfdecActionSpec swfdec_as_actions
   [SWFDEC_AS_ACTION_AND] = { "And", NULL, 2, 1, { NULL, /* FIXME */NULL, swfdec_action_logical, swfdec_action_logical, swfdec_action_logical } },
   [SWFDEC_AS_ACTION_OR] = { "Or", NULL, 2, 1, { NULL, /* FIXME */NULL, swfdec_action_logical, swfdec_action_logical, swfdec_action_logical } },
   [SWFDEC_AS_ACTION_NOT] = { "Not", NULL, 1, 1, { NULL, swfdec_action_not_4, swfdec_action_not_5, swfdec_action_not_5, swfdec_action_not_5 } },
-#if 0
-  [0x13] = { "StringEquals", NULL },
-  [0x14] = { "StringLength", NULL },
-  [0x15] = { "StringExtract", NULL },
-#endif
+  [SWFDEC_AS_ACTION_STRING_EQUALS] = { "StringEquals", NULL },
+  [SWFDEC_AS_ACTION_STRING_LENGTH] = { "StringLength", NULL },
+  [SWFDEC_AS_ACTION_STRING_EXTRACT] = { "StringExtract", NULL },
   [SWFDEC_AS_ACTION_POP] = { "Pop", NULL, 1, 0, { NULL, swfdec_action_pop, swfdec_action_pop, swfdec_action_pop, swfdec_action_pop } },
 #if 0
   [0x18] = { "ToInteger", NULL, 1, 1, { NULL, swfdec_action_to_integer, swfdec_action_to_integer, swfdec_action_to_integer, swfdec_action_to_integer } },
@@ -2165,31 +2163,33 @@ const SwfdecActionSpec swfdec_as_actions
 #if 0
   [0x21] = { "StringAdd", NULL, 2, 1, { NULL, swfdec_action_string_add, swfdec_action_string_add, swfdec_action_string_add, swfdec_action_string_add } },
 #endif
-  [0x22] = { "GetProperty", NULL, 2, 1, { NULL, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property } },
-  [0x23] = { "SetProperty", NULL, 3, 0, { NULL, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property } },
+  [SWFDEC_AS_ACTION_GET_PROPERTY] = { "GetProperty", NULL, 2, 1, { NULL, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property, swfdec_action_get_property } },
+  [SWFDEC_AS_ACTION_SET_PROPERTY] = { "SetProperty", NULL, 3, 0, { NULL, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property, swfdec_action_set_property } },
   [SWFDEC_AS_ACTION_CLONE_SPRITE] = { "CloneSprite", NULL },
   [SWFDEC_AS_ACTION_REMOVE_SPRITE] = { "RemoveSprite", NULL },
   [SWFDEC_AS_ACTION_TRACE] = { "Trace", NULL, 1, 0, { NULL, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace, swfdec_action_trace } },
 #if 0
   [0x27] = { "StartDrag", NULL, -1, 0, { NULL, swfdec_action_start_drag, swfdec_action_start_drag, swfdec_action_start_drag, swfdec_action_start_drag } },
   [0x28] = { "EndDrag", NULL, 0, 0, { NULL, swfdec_action_end_drag, swfdec_action_end_drag, swfdec_action_end_drag, swfdec_action_end_drag } },
-  [0x29] = { "StringLess", NULL },
-  /* version 7 */
-  [0x2a] = { "Throw", NULL },
-  [0x2b] = { "Cast", NULL },
-  [0x2c] = { "Implements", NULL },
 #endif
+  [SWFDEC_AS_ACTION_STRING_LESS] = { "StringLess", NULL },
+  /* version 7 */
+  [SWFDEC_AS_ACTION_THROW] = { "Throw", NULL },
+  [SWFDEC_AS_ACTION_CAST] = { "Cast", NULL },
+  [SWFDEC_AS_ACTION_IMPLEMENTS] = { "Implements", NULL },
   /* version 4 */
   [0x30] = { "RandomNumber", NULL, 1, 1, { NULL, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number, swfdec_action_random_number } },
+  [SWFDEC_AS_ACTION_MB_STRING_LENGTH] = { "MBStringLength", NULL },
+  [SWFDEC_AS_ACTION_CHAR_TO_ASCII] = { "CharToAscii", NULL },
+  [SWFDEC_AS_ACTION_ASCII_TO_CHAR] = { "AsciiToChar", NULL },
 #if 0
-  [0x31] = { "MBStringLength", NULL },
-  [0x32] = { "CharToAscii", NULL },
-  [0x33] = { "AsciiToChar", NULL },
   [0x34] = { "GetTime", NULL, 0, 1, { NULL, swfdec_action_get_time, swfdec_action_get_time, swfdec_action_get_time, swfdec_action_get_time } },
-  [0x35] = { "MBStringExtract", NULL },
-  [0x36] = { "MBCharToAscii", NULL },
-  [0x37] = { "MVAsciiToChar", NULL },
+#endif
+  [SWFDEC_AS_ACTION_MB_STRING_EXTRACT] = { "MBStringExtract", NULL },
+  [SWFDEC_AS_ACTION_MB_CHAR_TO_ASCII] = { "MBCharToAscii", NULL },
+  [SWFDEC_AS_ACTION_MB_ASCII_TO_CHAR] = { "MBAsciiToChar", NULL },
   /* version 5 */
+#if 0
   [0x3a] = { "Delete", NULL, 2, 0, { NULL, NULL, swfdec_action_delete, swfdec_action_delete, swfdec_action_delete } },
   [0x3b] = { "Delete2", NULL, 1, 0, { NULL, NULL, swfdec_action_delete2, swfdec_action_delete2, swfdec_action_delete2 } },
   [0x3c] = { "DefineLocal", NULL, 2, 0, { NULL, NULL, swfdec_action_define_local, swfdec_action_define_local, swfdec_action_define_local } },
@@ -2206,8 +2206,8 @@ const SwfdecActionSpec swfdec_as_actions
   [SWFDEC_AS_ACTION_TYPE_OF] = { "TypeOf", NULL, 1, 1, { NULL, NULL, swfdec_action_type_of, swfdec_action_type_of, swfdec_action_type_of } },
 #if 0
   [0x45] = { "TargetPath", NULL, 1, 1, { NULL, NULL, swfdec_action_target_path, swfdec_action_target_path, swfdec_action_target_path } },
-  [0x46] = { "Enumerate", NULL },
 #endif
+  [SWFDEC_AS_ACTION_ENUMERATE] = { "Enumerate", NULL },
   [SWFDEC_AS_ACTION_ADD2] = { "Add2", NULL, 2, 1, { NULL, NULL, swfdec_action_add2, swfdec_action_add2, swfdec_action_add2 } },
   [SWFDEC_AS_ACTION_LESS2] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
   [SWFDEC_AS_ACTION_EQUALS2] = { "Equals2", NULL, 2, 1, { NULL, NULL, swfdec_action_equals2, swfdec_action_equals2, swfdec_action_equals2 } },
@@ -2232,9 +2232,9 @@ const SwfdecActionSpec swfdec_as_actions
   [0x63] = { "BitLShift", NULL, 2, 1, { NULL, NULL, swfdec_action_shift, swfdec_action_shift, swfdec_action_shift } },
   [0x64] = { "BitRShift", NULL, 2, 1, { NULL, NULL, swfdec_action_shift, swfdec_action_shift, swfdec_action_shift } },
   [0x65] = { "BitURShift", NULL, 2, 1, { NULL, NULL, swfdec_action_shift, swfdec_action_shift, swfdec_action_shift } },
-  /* version 6 */
-  [0x66] = { "StrictEquals", NULL },
 #endif
+  /* version 6 */
+  [SWFDEC_AS_ACTION_STRICT_EQUALS] = { "StrictEquals", NULL },
   [SWFDEC_AS_ACTION_GREATER] = { "Greater", NULL, 2, 1, { NULL, NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
   [SWFDEC_AS_ACTION_STRING_GREATER] = { "StringGreater", NULL },
   /* version 7 */
@@ -2259,10 +2259,10 @@ const SwfdecActionSpec swfdec_as_actions
   [0x8d] = { "WaitForFrame2", swfdec_action_print_wait_for_frame2, 1, 0, { NULL, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2 } },
   /* version 7 */
   [0x8e] = { "DefineFunction2", swfdec_action_print_define_function, 0, -1, { NULL, NULL, NULL, swfdec_action_define_function, swfdec_action_define_function } },
-  [0x8f] = { "Try", NULL },
-  /* version 5 */
-  [0x94] = { "With", NULL },
 #endif
+  [SWFDEC_AS_ACTION_TRY] = { "Try", NULL },
+  /* version 5 */
+  [SWFDEC_AS_ACTION_WITH] = { "With", NULL },
   /* version 4 */
   [SWFDEC_AS_ACTION_PUSH] = { "Push", swfdec_action_print_push, 0, -1, { NULL, swfdec_action_push, swfdec_action_push, swfdec_action_push, swfdec_action_push } },
   [SWFDEC_AS_ACTION_JUMP] = { "Jump", swfdec_action_print_jump, 0, 0, { NULL, swfdec_action_jump, swfdec_action_jump, swfdec_action_jump, swfdec_action_jump } },
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 8148287..0315aa4 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -211,6 +211,10 @@ typedef enum {
   SWFDEC_AS_ACTION_MB_STRING_LENGTH = 0x31,
   SWFDEC_AS_ACTION_CHAR_TO_ASCII = 0x32,
   SWFDEC_AS_ACTION_ASCII_TO_CHAR = 0x33,
+  SWFDEC_AS_ACTION_GET_TIME = 0x34,
+  SWFDEC_AS_ACTION_MB_STRING_EXTRACT = 0x35,
+  SWFDEC_AS_ACTION_MB_CHAR_TO_ASCII = 0x36,
+  SWFDEC_AS_ACTION_MB_ASCII_TO_CHAR = 0x37,
   SWFDEC_AS_ACTION_DELETE = 0x3A,
   SWFDEC_AS_ACTION_DELETE2 = 0x3B,
   SWFDEC_AS_ACTION_DEFINE_LOCAL = 0x3C,
diff-tree 1c970914da071b97223cbe955a076fc31a6d458d (from 3f9d1cf43340a13945d5eb825292b811171d074f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 15:52:58 2007 +0200

    rework treatment of native functions (and there's not even a native function to test yet)
    
    Native functions are now executed in swfdec_context_run.
    This makes sure all execution is done in swfdec_context_run. This allows:
    - better debugging hooks, since it's only one function.
    - less error cases of which function does what to the current frame.
    Also new is that frames now reference the function they execute

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index e38d9ba..84ea82f 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -24,6 +24,7 @@
 #include <string.h>
 #include "swfdec_as_context.h"
 #include "swfdec_as_frame.h"
+#include "swfdec_as_function.h"
 #include "swfdec_as_interpret.h"
 #include "swfdec_as_object.h"
 #include "swfdec_as_stack.h"
@@ -353,7 +354,7 @@ swfdec_as_context_new (void)
 void
 swfdec_as_context_run (SwfdecAsContext *context)
 {
-  SwfdecAsFrame *frame;
+  SwfdecAsFrame *frame, *last_frame;
   SwfdecAsStack *stack;
   SwfdecScript *script;
   const SwfdecActionSpec *spec;
@@ -368,15 +369,26 @@ swfdec_as_context_run (SwfdecAsContext *
   void (* step) (SwfdecAsContext *context);
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+  if (context->frame == NULL)
+    return;
 
   klass = SWFDEC_AS_CONTEXT_GET_CLASS (context);
   step = klass->step;
 
+  last_frame = context->last_frame;
+  context->last_frame = context->frame->next;
 start:
   /* setup data */
   frame = context->frame;
-  if (frame == NULL)
-    return;
+  if (frame == context->last_frame)
+    goto out;
+  if (frame->function && frame->function->native) {
+    if (frame->argc >= frame->function->min_args) {
+      frame->function->native (context, frame->scope, frame->argc, frame->argv, frame->return_value);
+    }
+    swfdec_as_context_return (context);
+    goto start;
+  }
   script = frame->script;
   stack = frame->stack;
   version = SWFDEC_AS_EXTRACT_SCRIPT_VERSION (script->version);
@@ -472,6 +484,8 @@ start:
   }
 
 error:
+out:
+  context->last_frame = last_frame;
   return;
 }
 
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index ca1b818..c811db4 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -58,6 +58,7 @@ struct _SwfdecAsContext {
   /* execution state */
   unsigned int	      	version;	/* currently active version */
   SwfdecAsFrame *	frame;		/* topmost stack frame */
+  SwfdecAsFrame *	last_frame;   	/* last frame before calling context_run */
 };
 
 struct _SwfdecAsContextClass {
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index ee6c8ca..9f9381f 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -59,9 +59,15 @@ swfdec_as_frame_mark (SwfdecAsObject *ob
   swfdec_as_object_mark (frame->var_object);
   if (frame->target)
     swfdec_as_object_mark (frame->target);
+  if (frame->function)
+    swfdec_as_object_mark (SWFDEC_AS_OBJECT (frame->function));
   for (i = 0; i < frame->n_registers; i++) {
     swfdec_as_value_mark (&frame->registers[i]);
   }
+  /* FIXME: do we want this? */
+  for (i = 0; i < frame->argc; i++) {
+    swfdec_as_value_mark (&frame->argv[i]);
+  }
   swfdec_as_stack_mark (frame->stack);
   SWFDEC_AS_OBJECT_CLASS (swfdec_as_frame_parent_class)->mark (object);
 }
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index a89c7ee..5454fbd 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -39,11 +39,15 @@ struct _SwfdecAsFrame {
   SwfdecAsObject	object;
 
   SwfdecAsFrame *	next;		/* next frame (FIXME: keep a list in the context instead?) */
+  SwfdecAsFunction *	function;	/* function we're executing or NULL if toplevel */
+  /* debugging */
   char *		function_name;	/* name of function */
   SwfdecAsValue *	return_value;	/* pointer to where to store the return value */
+  guint			argc;		/* number of arguments */
+  SwfdecAsValue *	argv;		/* arguments */
   /* normal execution */
   SwfdecScript *	script;		/* script being executed */
-  SwfdecAsObject *	scope;		/* scope object coming after this: an Object */
+  SwfdecAsObject *	scope;		/* next scope object or this for native functions */
   SwfdecAsObject *	target;		/* target to use instead of last object in scope chain */
   SwfdecAsObject *	var_object;	/* new variables go here */
   SwfdecAsValue *	registers;	/* the registers */
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 653efea..0e52e7c 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -48,7 +48,7 @@ swfdec_as_function_mark (SwfdecAsObject 
   SwfdecAsFunction *function = SWFDEC_AS_FUNCTION (object);
 
   if (function->scope)
-    swfdec_as_object_mark (function->scope);
+    swfdec_as_object_mark (SWFDEC_AS_OBJECT (function->scope));
 
   SWFDEC_AS_OBJECT_CLASS (swfdec_as_function_parent_class)->mark (object);
 }
@@ -70,17 +70,19 @@ swfdec_as_function_init (SwfdecAsFunctio
 }
 
 SwfdecAsFunction *
-swfdec_as_function_new (SwfdecAsObject *scope, SwfdecScript *script)
+swfdec_as_function_new (SwfdecAsFrame *scope, SwfdecScript *script)
 {
   SwfdecAsFunction *fun;
+  SwfdecAsContext *context;
 
-  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (scope), NULL);
+  g_return_val_if_fail (SWFDEC_IS_AS_FRAME (scope), NULL);
   g_return_val_if_fail (script != NULL, NULL);
 
-  if (!swfdec_as_context_use_mem (scope->context, sizeof (SwfdecAsFunction)))
+  context = SWFDEC_AS_OBJECT (scope)->context;
+  if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsFunction)))
     return NULL;
   fun = g_object_new (SWFDEC_TYPE_AS_FUNCTION, NULL);
-  swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), scope->context, sizeof (SwfdecAsFunction));
+  swfdec_as_object_add (SWFDEC_AS_OBJECT (fun), context, sizeof (SwfdecAsFunction));
   fun->scope = scope;
   fun->script = script;
 
@@ -126,27 +128,17 @@ swfdec_as_function_call (SwfdecAsFunctio
     n_args = 0;
   }
   SWFDEC_AS_VALUE_SET_UNDEFINED (return_value);
+  frame->argc = n_args;
+  frame->argv = args;
+  frame->return_value = return_value;
+  frame->function = function;
   /* now do different things depending on if we're a native function or not */
   if (function->native) {
-    if (n_args < function->min_args) {
-      SwfdecAsStack *stack = context->frame->stack;
-      if (n_args == 0) {
-	swfdec_as_stack_ensure_size (stack, 1);
-	SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_push (stack));
-      } else {
-	stack->cur -= (n_args - 1);
-	SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (stack, 1));
-      }
-      return;
-    }
     frame = swfdec_as_frame_new_native (thisp);
     g_assert (function->name);
     frame->function_name = function->name;
-    function->native (context, thisp, n_args, args, return_value);
-    swfdec_as_context_return (context);
   } else {
     frame = swfdec_as_frame_new (thisp, function->script);
-    frame->return_value = return_value;
     /* FIXME: do the preloading here */
   }
 }
diff --git a/libswfdec/swfdec_as_function.h b/libswfdec/swfdec_as_function.h
index 77ca819..59df2ac 100644
--- a/libswfdec/swfdec_as_function.h
+++ b/libswfdec/swfdec_as_function.h
@@ -26,11 +26,8 @@
 
 G_BEGIN_DECLS
 
-typedef struct _SwfdecAsFunction SwfdecAsFunction;
 typedef struct _SwfdecAsFunctionClass SwfdecAsFunctionClass;
 
-typedef void (* SwfdecAsNativeCall) (SwfdecAsContext *context, SwfdecAsObject *thisp, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval);
-
 #define SWFDEC_TYPE_AS_FUNCTION                    (swfdec_as_function_get_type())
 #define SWFDEC_IS_AS_FUNCTION(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_FUNCTION))
 #define SWFDEC_IS_AS_FUNCTION_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_FUNCTION))
@@ -49,7 +46,7 @@ struct _SwfdecAsFunction {
 
   /* for script functions */
   SwfdecScript *	script;		/* script being executed or NULL when native */
-  SwfdecAsObject *	scope;		/* scope this function was defined in or NULL */
+  SwfdecAsFrame *	scope;		/* scope this function was defined in or NULL */
 };
 
 struct _SwfdecAsFunctionClass {
@@ -58,7 +55,7 @@ struct _SwfdecAsFunctionClass {
 
 GType			swfdec_as_function_get_type	(void);
 
-SwfdecAsFunction *	swfdec_as_function_new		(SwfdecAsObject *	scope,
+SwfdecAsFunction *	swfdec_as_function_new		(SwfdecAsFrame *	scope,
 							 SwfdecScript *		script);
 SwfdecAsFunction *	swfdec_as_function_new_native	(SwfdecAsContext *	context,
 							 SwfdecAsNativeCall	native,
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 2cfe796..8148287 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -37,9 +37,11 @@ typedef guint8 SwfdecAsType;
 typedef struct _SwfdecAsArray SwfdecAsArray;
 typedef struct _SwfdecAsContext SwfdecAsContext;
 typedef struct _SwfdecAsFrame SwfdecAsFrame;
+typedef struct _SwfdecAsFunction SwfdecAsFunction;
 typedef struct _SwfdecAsObject SwfdecAsObject;
 typedef struct _SwfdecAsStack SwfdecAsStack;
 typedef struct _SwfdecAsValue SwfdecAsValue;
+typedef void (* SwfdecAsNativeCall) (SwfdecAsContext *context, SwfdecAsObject *thisp, guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval);
 
 /* IMPORTANT: a SwfdecAsValue memset to 0 is a valid undefined value */
 struct _SwfdecAsValue {
diff-tree 3f9d1cf43340a13945d5eb825292b811171d074f (from 5804d93d45647d46e34f9916ea797e4156fa1572)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 15:49:53 2007 +0200

    make swfdec_action_get_target really get the target

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 23ab663..5ba5fb2 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -50,13 +50,18 @@
 static SwfdecMovie *
 swfdec_action_get_target (SwfdecAsContext *context)
 {
-  SwfdecAsObject *object = context->frame->scope;
+  SwfdecAsObject *target = context->frame->target;
 
-  if (!SWFDEC_IS_MOVIE (object)) {
+  if (target == NULL) {
+    target = SWFDEC_AS_OBJECT (context->frame);
+    while (SWFDEC_IS_AS_FRAME (target))
+      target = SWFDEC_AS_FRAME (target)->scope;
+  }
+  if (!SWFDEC_IS_MOVIE (target)) {
     SWFDEC_ERROR ("no valid target");
     return NULL;
   }
-  return SWFDEC_MOVIE (object);
+  return SWFDEC_MOVIE (target);
 }
 
 #if 0
diff-tree 5804d93d45647d46e34f9916ea797e4156fa1572 (from 6b880682674d50d6ab3d9ab7b2a4d5cccbe4691b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 15:18:05 2007 +0200

    make swfdec_as_object_call execute the call immediately

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 747b071..5cda61b 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -348,6 +348,7 @@ swfdec_as_object_call (SwfdecAsObject *o
   if (!SWFDEC_IS_AS_FUNCTION (fun))
     return;
   swfdec_as_function_call (fun, object, argc, argv, return_value ? return_value : &tmp);
+  swfdec_as_context_run (object->context);
 }
 
 gboolean
diff-tree 6b880682674d50d6ab3d9ab7b2a4d5cccbe4691b (from 02593459b3315d147733872fef67bdb8fb5396d0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Apr 12 15:05:55 2007 +0200

    restore correct order of SetProperty stack options

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 11ae005..23ab663 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -592,12 +592,12 @@ swfdec_action_set_property (SwfdecAsCont
   SwfdecAsObject *obj;
   guint id;
 
-  id = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx->frame->stack, 1));
+  id = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (cx->frame->stack, 2));
   if (id > (cx->version > 4 ? 21 : 18)) {
     SWFDEC_WARNING ("trying to SetProperty %u, not allowed", id);
     goto out;
   }
-  val = swfdec_as_stack_peek (cx->frame->stack, 2);
+  val = swfdec_as_stack_peek (cx->frame->stack, 1);
   swfdec_as_interpret_eval (cx, NULL, val);
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (val)) {
     obj = cx->frame->var_object;


More information about the Swfdec mailing list