[Swfdec] 11 commits - configure.ac libswfdec/swfdec_js_movie.c libswfdec/swfdec_root_movie.c libswfdec/swfdec_root_movie.h libswfdec/swfdec_script.c libswfdec/swfdec_sprite.c libswfdec/swfdec_sprite.h libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_tag.c test/trace

Benjamin Otte company at kemper.freedesktop.org
Mon Mar 5 08:31:46 PST 2007


 configure.ac                    |    2 
 libswfdec/swfdec_js_movie.c     |    3 -
 libswfdec/swfdec_root_movie.c   |   58 +++++++++++++++++++
 libswfdec/swfdec_root_movie.h   |   16 ++++-
 libswfdec/swfdec_script.c       |  119 ++++++++++++++++++++++++++++++++--------
 libswfdec/swfdec_sprite.c       |    6 +-
 libswfdec/swfdec_sprite.h       |    4 -
 libswfdec/swfdec_sprite_movie.c |   41 +++++++++++++
 libswfdec/swfdec_swf_decoder.c  |    5 -
 libswfdec/swfdec_tag.c          |   29 ++++-----
 test/trace/Makefile.am          |    2 
 test/trace/array.swf            |binary
 test/trace/array.swf.trace      |    8 ++
 13 files changed, 241 insertions(+), 52 deletions(-)

New commits:
diff-tree 1d7b4569b0f06d928f583a3e779137322aa86448 (from bc1fe2987c20d2425c0e7997270dea35aa168c92)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 17:29:51 2007 +0100

    oops, the cairo requirement should be >= 1.2 not >= 0.4

diff --git a/configure.ac b/configure.ac
index 2c45bf2..7f41b65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,7 +128,7 @@ if test "$HAVE_LIBOIL" = "no"; then
   AC_MSG_ERROR([cannot find liboil-0.3, which is required for build])
 fi
 
-PKG_CHECK_MODULES(CAIRO, cairo >= 0.4.0, HAVE_CAIRO=yes, HAVE_CAIRO=no)
+PKG_CHECK_MODULES(CAIRO, cairo >= 1.2.0, HAVE_CAIRO=yes, HAVE_CAIRO=no)
 AC_SUBST(CAIRO_LIBS)
 AC_SUBST(CAIRO_CFLAGS)
 if test "$HAVE_CAIRO" = "no"; then
diff-tree bc1fe2987c20d2425c0e7997270dea35aa168c92 (from 260cdc86a897a8f76a923c6deef48c1f28dc475b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 00:30:24 2007 +0100

    use per-character data to check if movie's DoInitAction has been run,
    and if not, run it

diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index d5545df..22e0458 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -32,6 +32,38 @@
 #include "swfdec_script.h"
 #include "swfdec_sprite.h"
 
+/*** SWFDEC_SPRITE_INFO ***/
+
+typedef struct _SwfdecSpriteInfo SwfdecSpriteInfo;
+struct _SwfdecSpriteInfo {
+  gboolean	 init_action_has_run;	/* TRUE if init actions have been run */ 
+};
+
+static void
+swfdec_sprite_info_free (gpointer infop)
+{
+  SwfdecSpriteInfo *info = infop;
+
+  g_free (info);
+}
+
+static SwfdecSpriteInfo *
+swfdec_sprite_info_get (SwfdecMovie *movie, SwfdecSprite *sprite)
+{
+  SwfdecRootMovie *root = SWFDEC_ROOT_MOVIE (movie->root);
+  SwfdecSpriteInfo *info;
+
+  info = swfdec_root_movie_get_character_data (root, SWFDEC_CHARACTER (sprite));
+  if (info == NULL) {
+    info = g_new0 (SwfdecSpriteInfo, 1);
+    swfdec_root_movie_set_character_data (root, SWFDEC_CHARACTER (sprite),
+	info, swfdec_sprite_info_free);
+  }
+  return info;
+}
+
+/*** SWFDEC_SPRITE_MOVIE ***/
+
 static SwfdecMovie *
 swfdec_sprite_movie_find (GList *movie_list, int depth)
 {
@@ -311,6 +343,15 @@ swfdec_sprite_movie_init_movie (SwfdecMo
   SwfdecSpriteMovie *movie = SWFDEC_SPRITE_MOVIE (mov);
 
   mov->n_frames = movie->sprite->n_frames;
+  if (movie->sprite->init_action) {
+    SwfdecSpriteInfo *info = swfdec_sprite_info_get (mov, movie->sprite);
+
+    if (!info->init_action_has_run) {
+      swfdec_script_execute (movie->sprite->init_action, 
+	  SWFDEC_SCRIPTABLE (mov->root));
+      info->init_action_has_run = TRUE;
+    }
+  }
   swfdec_sprite_movie_do_goto_frame (mov, GUINT_TO_POINTER (0));
   if (!swfdec_sprite_movie_iterate_end (mov)) {
     g_assert_not_reached ();
diff-tree 260cdc86a897a8f76a923c6deef48c1f28dc475b (from e6771bcb808217c72b9ceb8fa6c574165f6b3099)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 00:28:58 2007 +0100

    allow attaching runtime data to characters

diff --git a/libswfdec/swfdec_root_movie.c b/libswfdec/swfdec_root_movie.c
index 707f3b4..c21d32d 100644
--- a/libswfdec/swfdec_root_movie.c
+++ b/libswfdec/swfdec_root_movie.c
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "swfdec_root_movie.h"
+#include "swfdec_character.h"
 #include "swfdec_debug.h"
 #include "swfdec_decoder.h"
 #include "swfdec_flv_decoder.h"
@@ -126,6 +127,10 @@ swfdec_root_movie_dispose (GObject *obje
     g_object_unref (root->decoder);
     root->decoder = NULL;
   }
+  if (root->character_data != NULL) {
+    g_hash_table_destroy (root->character_data);
+    root->character_data = NULL;
+  }
 
   G_OBJECT_CLASS (swfdec_root_movie_parent_class)->dispose (object);
 }
@@ -209,3 +214,56 @@ swfdec_root_movie_load (SwfdecRootMovie 
   swfdec_player_launch (root->player, url, target);
 }
 
+typedef struct {
+  gpointer		data;
+  GDestroyNotify	free;
+} CharacterData;
+
+static void
+character_data_free (gpointer datap)
+{
+  CharacterData *data = datap;
+
+  if (data->free)
+    data->free (data->data);
+
+  g_free (data);
+}
+
+void
+swfdec_root_movie_set_character_data (SwfdecRootMovie *movie, 
+    SwfdecCharacter *character, gpointer data, GDestroyNotify destroy)
+{
+  CharacterData *cdata;
+
+  g_return_if_fail (SWFDEC_IS_ROOT_MOVIE (movie));
+  g_return_if_fail (SWFDEC_IS_CHARACTER (character));
+  g_return_if_fail (data != NULL);
+
+  cdata = g_new (CharacterData, 1);
+  cdata->data = data;
+  cdata->free = destroy;
+
+  if (movie->character_data == NULL) {
+    movie->character_data = g_hash_table_new_full (g_direct_hash, 
+	g_direct_equal, NULL, character_data_free);
+  }
+  g_hash_table_insert (movie->character_data, character, cdata);
+}
+
+gpointer
+swfdec_root_movie_get_character_data (SwfdecRootMovie *movie,
+    SwfdecCharacter *character)
+{
+  CharacterData *data;
+
+  g_return_val_if_fail (SWFDEC_IS_ROOT_MOVIE (movie), NULL);
+  g_return_val_if_fail (SWFDEC_IS_CHARACTER (character), NULL);
+
+  if (movie->character_data == NULL)
+    return NULL;
+  data = g_hash_table_lookup (movie->character_data, character);
+  if (!data)
+    return NULL;
+  return data->data;
+}
diff --git a/libswfdec/swfdec_root_movie.h b/libswfdec/swfdec_root_movie.h
index 59d65db..22fa503 100644
--- a/libswfdec/swfdec_root_movie.h
+++ b/libswfdec/swfdec_root_movie.h
@@ -43,6 +43,8 @@ struct _SwfdecRootMovie
   SwfdecLoader *	loader;		/* the loader providing data for the decoder */
   SwfdecDecoder *	decoder;	/* decoder that decoded all the stuff used by us */
   guint			unnamed_count;	/* variable used for naming unnamed movies */
+
+  GHashTable *		character_data;	/* custom data per character to be set by the movie using them */
 };
 
 struct _SwfdecRootMovieClass
@@ -50,12 +52,18 @@ struct _SwfdecRootMovieClass
   SwfdecSpriteMovieClass sprite_movie_class;
 };
 
-GType		swfdec_root_movie_get_type	(void);
+GType		swfdec_root_movie_get_type	  	(void);
 
-void		swfdec_root_movie_load		(SwfdecRootMovie *	movie,
-						 const char *		url,
-						 const char *		target);
+void		swfdec_root_movie_load			(SwfdecRootMovie *	movie,
+							 const char *		url,
+							 const char *		target);
 
+void		swfdec_root_movie_set_character_data	(SwfdecRootMovie *	movie,
+							 SwfdecCharacter *	character,
+							 gpointer		data,
+							 GDestroyNotify		destroy);
+gpointer	swfdec_root_movie_get_character_data	(SwfdecRootMovie *	movie,
+							 SwfdecCharacter *	character);
 
 G_END_DECLS
 #endif
diff-tree e6771bcb808217c72b9ceb8fa6c574165f6b3099 (from efce7d9c8c83c94695264ad55902cd78130141df)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Mar 5 00:28:11 2007 +0100

    only remove movie as property if it is one

diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index dcf119d..855d002 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -1154,7 +1154,8 @@ swfdec_js_movie_remove_property (SwfdecM
   JSContext *cx;
   JSBool found = JS_FALSE;
 
-  if (script->jsobj == NULL)
+  if (!movie->has_name ||
+      script->jsobj == NULL)
     return;
 
   cx = script->jscx;
diff-tree efce7d9c8c83c94695264ad55902cd78130141df (from f7b8a791525df2b8f431ce233219f25cd694428a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Mar 4 23:35:07 2007 +0100

    implement Delete2
    
    also change assertion to SWFDEC_ERROR, we don't wanna crash

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index f51a3d2..7f0a833 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1763,6 +1763,26 @@ swfdec_action_delete (JSContext *cx, gui
 }
 
 static JSBool
+swfdec_action_delete2 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  const char *name;
+  JSObject *obj, *pobj;
+  JSProperty *prop;
+  JSAtom *atom;
+  
+  cx->fp->sp -= 2;
+  name = swfdec_js_to_string (cx, cx->fp->sp[1]);
+  if (name == NULL)
+    return JS_FALSE;
+  if (!(atom = js_Atomize (cx, name, strlen (name), 0)) ||
+      !js_FindProperty (cx, (jsid) atom, &obj, &pobj, &prop))
+    return JS_FALSE;
+  if (!pobj)
+    return JS_TRUE;
+  return JS_DeleteProperty (cx, pobj, name);
+}
+
+static JSBool
 swfdec_action_store_register (JSContext *cx, guint action, const guint8 *data, guint len)
 {
   if (len != 1) {
@@ -2169,7 +2189,7 @@ static const SwfdecActionSpec actions[25
   [0x37] = { "MVAsciiToChar", NULL },
   /* version 5 */
   [0x3a] = { "Delete", NULL, 2, 0, { NULL, NULL, swfdec_action_delete, swfdec_action_delete, swfdec_action_delete } },
-  [0x3b] = { "Delete2", NULL },
+  [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 } },
   [0x3d] = { "CallFunction", NULL, -1, 1, { NULL, NULL, swfdec_action_call_function, swfdec_action_call_function, swfdec_action_call_function } },
   [0x3e] = { "Return", NULL, 1, 0, { NULL, NULL, swfdec_action_return, swfdec_action_return, swfdec_action_return } },
@@ -2470,7 +2490,10 @@ swfdec_script_interpret (SwfdecScript *s
     if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER ||
 	script->flags & SWFDEC_SCRIPT_PRELOAD_ROOT ||
 	script->flags & SWFDEC_SCRIPT_PRELOAD_PARENT) {
-      g_assert_not_reached ();
+      SWFDEC_ERROR ("The following preload flags aren't implemented:%s%s%s",
+	  script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER ? " PRELOAD_SUPER" : "",
+	  script->flags & SWFDEC_SCRIPT_PRELOAD_ROOT ? " PRELOAD_ROOT" : "",
+	  script->flags & SWFDEC_SCRIPT_PRELOAD_PARENT ? " PRELOAD_PARENT" : "");
     }
     if (script->flags & SWFDEC_SCRIPT_PRELOAD_GLOBAL)
       fp->vars[preload_reg++] = OBJECT_TO_JSVAL (player->jsobj);
diff-tree f7b8a791525df2b8f431ce233219f25cd694428a (from 59aa2d0990e32ec1996df5b233cb0355e2381b8a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Mar 4 23:24:37 2007 +0100

    implement ActionToNumber
    
    also document swfdec_script_execute

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 762264c..f51a3d2 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1814,6 +1814,15 @@ swfdec_action_modulo_7 (JSContext *cx, g
   }
 }
 
+static JSBool
+swfdec_action_to_number (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  double d;
+  if (!JS_ValueToNumber (cx, cx->fp->sp[-1], &d))
+    return JS_FALSE;
+  return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
+}
+
 /*** PRINT FUNCTIONS ***/
 
 static char *
@@ -2175,7 +2184,7 @@ static const SwfdecActionSpec actions[25
   [0x47] = { "Add2", NULL, 2, 1, { NULL, NULL, swfdec_action_add2_5, swfdec_action_add2_5, swfdec_action_add2_7 } },
   [0x48] = { "Less2", NULL, 2, 1, { NULL, NULL, swfdec_action_new_comparison_6, swfdec_action_new_comparison_6, swfdec_action_new_comparison_7 } },
   [0x49] = { "Equals2", NULL, 2, 1, { NULL, NULL, swfdec_action_equals2, swfdec_action_equals2, swfdec_action_equals2 } },
-  [0x4a] = { "ToNumber", NULL },
+  [0x4a] = { "ToNumber", NULL, 1, 1, { NULL, NULL, swfdec_action_to_number, swfdec_action_to_number, swfdec_action_to_number } },
   [0x4b] = { "ToString", NULL },
   [0x4c] = { "PushDuplicate", NULL, 1, 2, { NULL, NULL, swfdec_action_push_duplicate, swfdec_action_push_duplicate, swfdec_action_push_duplicate } },
   [0x4d] = { "Swap", NULL },
@@ -2643,6 +2652,17 @@ swfdec_script_ensure_function (SwfdecScr
   return script->fun;
 }
 
+/**
+ * swfdec_script_execute:
+ * @script: a #SwfdecScript to execute
+ * @scriptable: #SwfdecScriptable to use as this in script scope
+ *
+ * Executes @script in the context of @scriptable. No local scope will be 
+ * added, so no local variables can exist. As per Actionscript, 4 registers
+ * will be created.
+ *
+ * Returns: the return value of @script
+ **/
 jsval
 swfdec_script_execute (SwfdecScript *script, SwfdecScriptable *scriptable)
 {
diff-tree 59aa2d0990e32ec1996df5b233cb0355e2381b8a (from e9391a04c8c57250fe0032668bedfd2d494e9ffc)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Mar 4 19:40:55 2007 +0100

    s/swfdec_action_to_number/swfdec_value_to_number/

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 6a3e90c..762264c 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -155,7 +155,7 @@ swfdec_action_push_string (JSContext *cx
 }
 
 static double
-swfdec_action_to_number (JSContext *cx, jsval val)
+swfdec_value_to_number (JSContext *cx, jsval val)
 {
   if (JSVAL_IS_INT (val)) {
     return JSVAL_TO_INT (val);
@@ -300,7 +300,7 @@ swfdec_value_to_frame (JSContext *cx, Sw
     frame = swfdec_sprite_get_frame (SWFDEC_SPRITE_MOVIE (movie)->sprite, name);
   } else {
     /* FIXME: how do we treat undefined etc? */
-    frame = swfdec_action_to_number (cx, val);
+    frame = swfdec_value_to_number (cx, val);
   }
   return frame;
 }
@@ -824,8 +824,8 @@ swfdec_action_binary (JSContext *cx, gui
   rval = cx->fp->sp[-1];
   lval = cx->fp->sp[-2];
   if (((SwfdecScript *) cx->fp->swf)->version < 7) {
-    l = swfdec_action_to_number (cx, lval);
-    r = swfdec_action_to_number (cx, rval);
+    l = swfdec_value_to_number (cx, lval);
+    r = swfdec_value_to_number (cx, rval);
   } else {
     if (!swfdec_value_to_number_7 (cx, lval, &l) ||
         !swfdec_value_to_number_7 (cx, rval, &r))
@@ -901,8 +901,8 @@ swfdec_action_add2_5 (JSContext *cx, gui
     cx->fp->sp[-1] = STRING_TO_JSVAL (str);
   } else {
     double d, d2;
-    d = swfdec_action_to_number (cx, lval);
-    d2 = swfdec_action_to_number (cx, rval);
+    d = swfdec_value_to_number (cx, lval);
+    d2 = swfdec_value_to_number (cx, rval);
     d += d2;
     cx->fp->sp--;
     return JS_NewNumberValue(cx, d, &cx->fp->sp[-1]);
@@ -991,8 +991,8 @@ swfdec_action_new_comparison_6 (JSContex
   rval = cx->fp->sp[-1];
   lval = cx->fp->sp[-2];
   cx->fp->sp--;
-  d = swfdec_action_to_number (cx, lval);
-  d2 = swfdec_action_to_number (cx, rval);
+  d = swfdec_value_to_number (cx, lval);
+  d2 = swfdec_value_to_number (cx, rval);
   if (action == 0x48)
     cx->fp->sp[-1] = BOOLEAN_TO_JSVAL (d < d2);
   else 
@@ -1028,7 +1028,7 @@ swfdec_action_not_4 (JSContext *cx, guin
 {
   double d;
 
-  d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+  d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
   cx->fp->sp[-1] = INT_TO_JSVAL (d == 0 ? 1 : 0);
   return JS_TRUE;
 }
@@ -1038,7 +1038,7 @@ swfdec_action_not_5 (JSContext *cx, guin
 {
   double d;
 
-  d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+  d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
   cx->fp->sp[-1] = d == 0 ? JSVAL_TRUE : JSVAL_FALSE;
   return JS_TRUE;
 }
@@ -1063,7 +1063,7 @@ swfdec_action_if (JSContext *cx, guint a
     SWFDEC_ERROR ("Jump action length invalid (is %u, should be 2", len);
     return JS_FALSE;
   }
-  d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+  d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
   cx->fp->sp--;
   if (d != 0)
     cx->fp->pc += 5 + GINT16_FROM_LE (*((gint16*) data)); 
@@ -1075,7 +1075,7 @@ swfdec_action_decrement (JSContext *cx, 
 {
   double d;
 
-  d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+  d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
   d--;
   return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
 }
@@ -1085,7 +1085,7 @@ swfdec_action_increment (JSContext *cx, 
 {
   double d;
 
-  d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+  d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
   d++;
   return JS_NewNumberValue (cx, d, &cx->fp->sp[-1]);
 }
@@ -1199,8 +1199,8 @@ swfdec_action_old_compare (JSContext *cx
 
   rval = cx->fp->sp[-1];
   lval = cx->fp->sp[-2];
-  l = swfdec_action_to_number (cx, lval);
-  r = swfdec_action_to_number (cx, rval);
+  l = swfdec_value_to_number (cx, lval);
+  r = swfdec_value_to_number (cx, rval);
   switch (action) {
     case 0x0e:
       cond = l == r;
@@ -1340,7 +1340,7 @@ swfdec_action_start_drag (JSContext *cx,
     return JS_FALSE;
   if (!swfdec_eval_jsval (cx, NULL, &fp->sp[-1]))
     return JS_FALSE;
-  if (swfdec_action_to_number (cx, fp->sp[-3])) {
+  if (swfdec_value_to_number (cx, fp->sp[-3])) {
     jsval tmp;
     if (stack_size < 7)
       return JS_FALSE;
@@ -1683,7 +1683,7 @@ swfdec_action_shift (JSContext *cx, guin
 static JSBool
 swfdec_action_to_integer (JSContext *cx, guint action, const guint8 *data, guint len)
 {
-  double d = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+  double d = swfdec_value_to_number (cx, cx->fp->sp[-1]);
 
   return JS_NewNumberValue (cx, (int) d, &cx->fp->sp[-1]);
 }
@@ -1782,8 +1782,8 @@ swfdec_action_modulo_5 (JSContext *cx, g
 {
   double x, y;
 
-  x = swfdec_action_to_number (cx, cx->fp->sp[-1]);
-  y = swfdec_action_to_number (cx, cx->fp->sp[-2]);
+  x = swfdec_value_to_number (cx, cx->fp->sp[-1]);
+  y = swfdec_value_to_number (cx, cx->fp->sp[-2]);
   cx->fp->sp--;
   errno = 0;
   x = fmod (x, y);
diff-tree e9391a04c8c57250fe0032668bedfd2d494e9ffc (from fba2a11a1aa81b12f2d9203653e7e6f1011f216e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Mar 4 19:35:43 2007 +0100

    add array test

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 96d586f..8322668 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -8,6 +8,8 @@ trace_LDFLAGS = $(SWF_LIBS) $(CAIRO_LIBS
 
 EXTRA_DIST = \
 	README \
+	array.swf \
+	array.swf.trace \
 	case1-6.swf \
 	case1-6.swf.trace \
 	case1-7.swf \
diff --git a/test/trace/array.swf b/test/trace/array.swf
new file mode 100755
index 0000000..2973976
Binary files /dev/null and b/test/trace/array.swf differ
diff --git a/test/trace/array.swf.trace b/test/trace/array.swf.trace
new file mode 100755
index 0000000..2e33764
--- /dev/null
+++ b/test/trace/array.swf.trace
@@ -0,0 +1,8 @@
+Test array basics
+1,2,3,4,5
+1
+2
+3
+4
+5
+5
diff-tree fba2a11a1aa81b12f2d9203653e7e6f1011f216e (from ea4dcb58d789607a0e48c9d3bf17b210fd1969ea)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Mar 4 19:35:17 2007 +0100

    implement ActionInitArray

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 6e75785..6a3e90c 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1459,6 +1459,36 @@ swfdec_action_init_object (JSContext *cx
 }
 
 static JSBool
+swfdec_action_init_array (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  JSStackFrame *fp = cx->fp;
+  JSObject *array;
+  int i, j;
+  guint n_items;
+
+  if (!JS_ValueToECMAUint32 (cx, fp->sp[-1], &n_items))
+    return JS_FALSE;
+  if ((guint) (fp->sp - fp->spbase) < n_items + 1) {
+    SWFDEC_ERROR ("not enough stack space");
+    return JS_FALSE;
+  }
+
+  /* items are the wrong order on the stack */
+  j = - 1 - n_items;
+  for (i = - 2; i > j; i--, j++) {
+    jsval tmp = fp->sp[i];
+    fp->sp[i] = fp->sp[j];
+    fp->sp[j] = tmp;
+  }
+  array = JS_NewArrayObject (cx, n_items, fp->sp - n_items - 1);
+  if (array == NULL)
+    return JS_FALSE;
+  fp->sp -= n_items;
+  fp->sp[-1] = OBJECT_TO_JSVAL (array);
+  return JS_TRUE;
+}
+
+static JSBool
 swfdec_action_do_define_function (JSContext *cx, guint action,
     const guint8 *data, guint len, gboolean v2)
 {
@@ -2137,7 +2167,7 @@ static const SwfdecActionSpec actions[25
   [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 } },
-  [0x42] = { "InitArray", NULL },
+  [0x42] = { "InitArray", NULL, -1, 1, { NULL, NULL, swfdec_action_init_array, swfdec_action_init_array, swfdec_action_init_array } },
   [0x43] = { "InitObject", NULL, -1, 1, { NULL, NULL, swfdec_action_init_object, swfdec_action_init_object, swfdec_action_init_object } },
   [0x44] = { "Typeof", NULL },
   [0x45] = { "TargetPath", NULL, 1, 1, { NULL, NULL, swfdec_action_target_path, swfdec_action_target_path, swfdec_action_target_path } },
diff-tree ea4dcb58d789607a0e48c9d3bf17b210fd1969ea (from e195ae34fffdd9ce861a1466529078bdc3db2a11)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Mar 4 17:12:37 2007 +0100

    read DoInitAction contents

diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c
index 4145c72..f5496b9 100644
--- a/libswfdec/swfdec_sprite.c
+++ b/libswfdec/swfdec_sprite.c
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-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
@@ -84,6 +84,10 @@ swfdec_sprite_dispose (GObject *object)
     }
     g_free(sprite->frames);
   }
+  if (sprite->init_action) {
+    swfdec_script_unref (sprite->init_action);
+    sprite->init_action = NULL;
+  }
 
   G_OBJECT_CLASS (swfdec_sprite_parent_class)->dispose (object);
 }
diff --git a/libswfdec/swfdec_sprite.h b/libswfdec/swfdec_sprite.h
index 6df8539..e4c7467 100644
--- a/libswfdec/swfdec_sprite.h
+++ b/libswfdec/swfdec_sprite.h
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-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
@@ -72,6 +72,7 @@ struct _SwfdecSprite
 
   SwfdecSpriteFrame *	frames;		/* the n_frames different frames */
   unsigned int		n_frames;	/* number of frames in this sprite */
+  SwfdecScript *	init_action;	/* action to run when initializing this sprite */
 
   /* parse state */
   unsigned int		parse_frame;	/* frame we're currently parsing. == n_frames if done parsing */
diff --git a/libswfdec/swfdec_tag.c b/libswfdec/swfdec_tag.c
index 9fd2491..fab6c1f 100644
--- a/libswfdec/swfdec_tag.c
+++ b/libswfdec/swfdec_tag.c
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-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
@@ -286,22 +286,21 @@ int
 tag_func_do_init_action (SwfdecSwfDecoder * s)
 {
   SwfdecBits *bits = &s->b;
-  SwfdecBuffer *buffer;
-  SwfdecCharacter *character;
-
-  character = swfdec_swf_decoder_get_character (s, swfdec_bits_get_u16 (bits));
-  buffer = swfdec_bits_get_buffer (bits, -1);
+  guint id;
+  SwfdecSprite *sprite;
 
-  if (SWFDEC_IS_SPRITE (character)) {
-    SWFDEC_WARNING ("init actions not implemented yet");
-#if 0
-    SwfdecSprite *save_parse_sprite = s->parse_sprite;
-    s->parse_sprite = SWFDEC_SPRITE(obj);
-    retcode = swfdec_action_script_execute (s, buffer);
-    s->parse_sprite = save_parse_sprite;
-#endif
+  id = swfdec_bits_get_u16 (bits);
+  sprite = swfdec_swf_decoder_get_character (s, id);
+  if (!SWFDEC_IS_SPRITE (sprite)) {
+    SWFDEC_ERROR ("character %u is not a sprite", id);
+    return SWFDEC_STATUS_OK;
+  }
+  if (sprite->init_action != NULL) {
+    SWFDEC_ERROR ("sprite %u already has an init action", id);
+    return SWFDEC_STATUS_OK;
   }
-  swfdec_buffer_unref (buffer);
+  sprite->init_action = swfdec_script_new_for_player (SWFDEC_DECODER (s)->player,
+      bits, "InitAction", s->version);
 
   return SWFDEC_STATUS_OK;
 }
diff-tree e195ae34fffdd9ce861a1466529078bdc3db2a11 (from 10106c5992d19bf126c2e32e0761eee05d72b0c2)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Mar 4 15:46:11 2007 +0100

    No need for storing the player in the script anymore

diff --git a/libswfdec/swfdec_sprite.h b/libswfdec/swfdec_sprite.h
index 5ac0bf8..6df8539 100644
--- a/libswfdec/swfdec_sprite.h
+++ b/libswfdec/swfdec_sprite.h
@@ -70,7 +70,6 @@ struct _SwfdecSprite
 {
   SwfdecGraphic		graphic;
 
-  SwfdecPlayer *	player;		/* FIXME: only needed to get the JS Context, I want it gone */
   SwfdecSpriteFrame *	frames;		/* the n_frames different frames */
   unsigned int		n_frames;	/* number of frames in this sprite */
 
diff --git a/libswfdec/swfdec_swf_decoder.c b/libswfdec/swfdec_swf_decoder.c
index 0bc1099..2a45d5e 100644
--- a/libswfdec/swfdec_swf_decoder.c
+++ b/libswfdec/swfdec_swf_decoder.c
@@ -240,7 +240,6 @@ swfdec_swf_decoder_parse (SwfdecDecoder 
 
   s->b = s->parse;
   g_assert (dec->player);
-  s->main_sprite->player = dec->player;
 
   switch (s->state) {
     case SWFDEC_STATE_INIT1:
@@ -423,10 +422,6 @@ swfdec_swf_decoder_create_character (Swf
   result = g_object_new (type, NULL);
   result->id = id;
   s->characters = g_list_prepend (s->characters, result);
-  if (SWFDEC_IS_SPRITE (result)) {
-    g_assert (SWFDEC_DECODER (s)->player);
-    SWFDEC_SPRITE (result)->player = SWFDEC_DECODER (s)->player;
-  }
   if (SWFDEC_IS_CACHED (result)) {
     swfdec_cached_set_cache (SWFDEC_CACHED (result), SWFDEC_DECODER (s)->player->cache);
   }


More information about the Swfdec mailing list