[Swfdec] 2 commits - libswfdec/swfdec_debugger.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h

Benjamin Otte
Tue, 13 Mar 2007 04:51:40 -0000

libswfdec/swfdec_debugger.c |  122 +++++++++++++++++++++++++++++++++++++++++---
 libswfdec/swfdec_script.c   |   38 +++++++------
 libswfdec/swfdec_script.h   |    9 +++
 3 files changed, 145 insertions(+), 24 deletions(-)

New commits:
diff-tree f3ceb92e7405d2cef3398baa79712eaee6eeabd1 (from
b1cd2edf289dde1bd89d3c513da13b4cf27bdf13)
Author: Benjamin Otte <otte@gnome.org>
Date:   Tue Mar 13 11:57:49 2007 +0100

    print constant pool strings verbatim instead of printing "Pool x"

diff --git a/libswfdec/swfdec_debugger.c b/libswfdec/swfdec_debugger.c
index 7f3546d..c17c315 100644
--- a/libswfdec/swfdec_debugger.c
+++ b/libswfdec/swfdec_debugger.c
@@ -32,32 +32,138 @@

 /*** SwfdecDebuggerScript ***/

+typedef struct {
+  SwfdecConstantPool *	constant_pool;	/* current constant pool */
+  GArray *		commands;	/* SwfdecDebuggerCommands parsed so far */
+} ScriptParser;
+
+static char *
+swfdec_debugger_print_push (ScriptParser *parser, const guint8 *data, guint
len)
+{
+  gboolean first = TRUE;
+  SwfdecBits bits;
+  GString *string = g_string_new ("Push");
+
+  swfdec_bits_init_data (&bits, data, len);
+  while (swfdec_bits_left (&bits)) {
+    guint type = swfdec_bits_get_u8 (&bits);
+    if (first)
+      g_string_append (string, " ");
+    else
+      g_string_append (string, ", ");
+    first = FALSE;
+    switch (type) {
+      case 0: /* string */
+	{
+	  const char *s = swfdec_bits_skip_string (&bits);
+	  if (!s) {
+	    g_string_free (string, TRUE);
+	    return NULL;
+	  }
+	  g_string_append_c (string, '"');
+	  g_string_append (string, s);
+	  g_string_append_c (string, '"');
+	  break;
+	}
+      case 1: /* float */
+	g_string_append_printf (string, "%g", swfdec_bits_get_float
(&bits));
+	break;
+      case 2: /* null */
+	g_string_append (string, "null");
+	break;
+      case 3: /* undefined */
+	g_string_append (string, "undefined");
+	break;
+      case 4: /* register */
+	g_string_append_printf (string, "Register %u", swfdec_bits_get_u8
(&bits));
+	break;
+      case 5: /* boolean */
+	g_string_append (string, swfdec_bits_get_u8 (&bits) ? "True" :
"False");
+	break;
+      case 6: /* double */
+	g_string_append_printf (string, "%g", swfdec_bits_get_double
(&bits));
+	break;
+      case 7: /* 32bit int */
+	g_string_append_printf (string, "%d", swfdec_bits_get_u32
(&bits));
+	break;
+      case 8: /* 8bit ConstantPool address */
+      case 9: /* 16bit ConstantPool address */
+	{
+	  guint id;
+	  const char *s;
+
+	  if (!parser->constant_pool) {
+	    SWFDEC_ERROR ("no constant pool");
+	    g_string_free (string, TRUE);
+	    return NULL;
+	  }
+	  id = type == 8 ? swfdec_bits_get_u8 (&bits) : swfdec_bits_get_u16
(&bits);
+	  s = swfdec_constant_pool_get (parser->constant_pool, id);
+	  if (!s) {
+	    SWFDEC_ERROR ("constant pool size too small");
+	    g_string_free (string, TRUE);
+	    return NULL;
+	  }
+	  g_string_append_c (string, '"');
+	  g_string_append (string, s);
+	  g_string_append_c (string, '"');
+	}
+	break;
+      default:
+	SWFDEC_ERROR ("Push: type %u not implemented", type);
+	return JS_FALSE;
+    }
+  }
+  return g_string_free (string, FALSE);
+}
+
+/* NB: constant pool actions are special in that they are called at init time
*/
 static gboolean
 swfdec_debugger_add_command (gconstpointer bytecode, guint action,
-    const guint8 *data, guint len, gpointer arrayp)
+    const guint8 *data, guint len, gpointer parserp)
 {
+  ScriptParser *parser = parserp;
   SwfdecDebuggerCommand command;

   command.code = bytecode;
   command.breakpoint = 0;
-  command.description = swfdec_script_print_action (action, data, len);
-  g_array_append_val (arrayp, command);
+  if (action == 0x96) {
+    /* PUSH */
+    command.description = swfdec_debugger_print_push (parser, data, len);
+  } else {
+    command.description = swfdec_script_print_action (action, data, len);
+  }
+  g_array_append_val (parser->commands, command);
+  if (action == 0x88) {
+    /* constant pool */
+    if (parser->constant_pool)
+      swfdec_constant_pool_free (parser->constant_pool);
+    parser->constant_pool = swfdec_constant_pool_new_from_action (data,
len);
+  }
   return TRUE;
 }

 static SwfdecDebuggerScript *
 swfdec_debugger_script_new (SwfdecScript *script)
 {
-  GArray *array;
+  ScriptParser parser;
   SwfdecDebuggerScript *ret;

   ret = g_new0 (SwfdecDebuggerScript, 1);
   ret->script = script;
   swfdec_script_ref (script);
-  array = g_array_new (TRUE, FALSE, sizeof (SwfdecDebuggerCommand));
-  swfdec_script_foreach (script, swfdec_debugger_add_command, array);
-  ret->n_commands = array->len;
-  ret->commands = (SwfdecDebuggerCommand *) g_array_free (array, FALSE);
+  parser.commands = g_array_new (TRUE, FALSE, sizeof (SwfdecDebuggerCommand));
+  if (script->constant_pool) {
+    parser.constant_pool = swfdec_constant_pool_new_from_action (
+	script->constant_pool->data + 3, script->constant_pool->length -
3);
+  } else {
+    parser.constant_pool = NULL;
+  }
+  swfdec_script_foreach (script, swfdec_debugger_add_command, &parser);
+  ret->n_commands = parser.commands->len;
+  ret->commands = (SwfdecDebuggerCommand *) g_array_free (parser.commands,
FALSE);
+  if (parser.constant_pool)
+    swfdec_constant_pool_free (parser.constant_pool);

   return ret;
 }
diff-tree b1cd2edf289dde1bd89d3c513da13b4cf27bdf13 (from
d569f40ce1d270b721fd0b1fb12ed77a512d6e74)
Author: Benjamin Otte <otte@gnome.org>
Date:   Tue Mar 13 11:54:30 2007 +0100

    make this more debugger-friendly

    - export SwfdecConstantPool
    - ensure scripts are only added to the player when they are completely
      initialized.

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index ac47a97..e261d61 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -43,9 +43,7 @@

 /*** CONSTANT POOLS ***/

-typedef GPtrArray SwfdecConstantPool;
-
-static SwfdecConstantPool *
+SwfdecConstantPool *
 swfdec_constant_pool_new_from_action (const guint8 *data, guint len)
 {
   guint8 *next;
@@ -79,20 +77,20 @@ swfdec_constant_pool_new_from_action (co
   return pool;
 }

-static guint
+guint
 swfdec_constant_pool_size (SwfdecConstantPool *pool)
 {
   return pool->len;
 }

-static const char *
+const char *
 swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i)
 {
   g_assert (i < pool->len);
   return g_ptr_array_index (pool, i);
 }

-static void
+void
 swfdec_constant_pool_free (SwfdecConstantPool *pool)
 {
   g_ptr_array_free (pool, TRUE);
@@ -125,6 +123,15 @@ swfdec_constant_pool_get_area (SwfdecScr

 /*** SUPPORT FUNCTIONS ***/

+static void
+swfdec_script_add_to_player (SwfdecScript *script, SwfdecPlayer *player)
+{
+  if (SWFDEC_IS_DEBUGGER (player)) {
+    swfdec_debugger_add_script (SWFDEC_DEBUGGER (player), script);
+    script->debugger = player;
+  }
+}
+
 /**
  * swfdec_script_ensure_stack:
  * @cx: #JSContext to check
@@ -1733,22 +1740,22 @@ swfdec_action_define_function (JSContext
     }
     if (name == NULL)
       name = "unnamed_function";
-    script = swfdec_script_new_for_player (JS_GetContextPrivate (cx),
-	&bits, name, ((SwfdecScript *) cx->fp->swf)->version);
+    script = swfdec_script_new (&bits, name, ((SwfdecScript *)
cx->fp->swf)->version);
     swfdec_buffer_unref (buffer);
-    if (cx->fp->constant_pool) {
-      script->constant_pool = swfdec_constant_pool_get_area
(cx->fp->swf,
-	  cx->fp->constant_pool);
-    }
   }
   if (script == NULL) {
     SWFDEC_ERROR ("failed to create script");
     g_free (preloads);
     return JS_FALSE;
   }
+  if (cx->fp->constant_pool) {
+    script->constant_pool = swfdec_constant_pool_get_area
(cx->fp->swf,
+	cx->fp->constant_pool);
+  }
   script->flags = flags;
   script->preloads = preloads;
   fun->swf = script;
+  swfdec_script_add_to_player (script, JS_GetContextPrivate (cx));
   /* attach the function */
   if (*function_name == '\0') {
     if (cx->fp->sp >= cx->fp->spend) {
@@ -2170,6 +2177,7 @@ swfdec_action_print_set_target (guint ac
   }
   return g_strconcat ("SetTarget ", data, NULL);
 }
+
 static char *
 swfdec_action_print_define_function (guint action, const guint8 *data, guint
len)
 {
@@ -2664,10 +2672,8 @@ swfdec_script_new_for_player (SwfdecPlay
   g_return_val_if_fail (bits != NULL, NULL);

   script = swfdec_script_new (bits, name, version);
-  if (SWFDEC_IS_DEBUGGER (player) && script) {
-    swfdec_debugger_add_script (SWFDEC_DEBUGGER (player), script);
-    script->debugger = player;
-  }
+  if (script)
+    swfdec_script_add_to_player (script, player);
   return script;
 }

diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h
index 8af5755..d55cdbc 100644
--- a/libswfdec/swfdec_script.h
+++ b/libswfdec/swfdec_script.h
@@ -28,6 +28,7 @@
 G_BEGIN_DECLS

 //typedef struct _SwfdecScript SwfdecScript;
+typedef GPtrArray SwfdecConstantPool;

 typedef enum {
   SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0),
@@ -62,6 +63,14 @@ struct _SwfdecScript {
 const char *	swfdec_action_get_name		(guint			action);
 guint		swfdec_action_get_from_name	(const char *		name);

+SwfdecConstantPool *
+		swfdec_constant_pool_new_from_action (const guint8 *	data,
+						 guint			len);
+guint		swfdec_constant_pool_size	(SwfdecConstantPool *	pool);
+const char *	swfdec_constant_pool_get	(SwfdecConstantPool *	pool,
+						 guint			i);
+void		swfdec_constant_pool_free	(SwfdecConstantPool *	pool);
+
 SwfdecScript *	swfdec_script_new		(SwfdecBits *		bits,
 						 const char *		name,
 						 unsigned int	      	version);