Benjamin Otte
2007-Mar-13 04:51 UTC
[Swfdec] 2 commits - libswfdec/swfdec_debugger.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h
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);
Apparently Analagous Threads
- Branch 'as' - 13 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h
- Branch 'interpreter' - 9 commits - libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_debugger.c libswfdec/swfdec_debugger.h libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_event.c libswfdec/swfdec_js.c libswfdec/swfdec_js_global.c
- Branch 'interpreter' - 4 commits - libswfdec/js libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_codec_screen.c libswfdec/swfdec_image.c libswfdec/swfdec_script.c libswfdec/swfdec_swf_decoder.c libswfdec/swfdec_tag.c
- Branch 'as' - 9 commits - libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_stack.c libswfdec/swfdec_as_stack.h
- 5 commits - libswfdec/swfdec_as_interpret.c libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_debugger.c libswfdec/swfdec_movie.c libswfdec/swfdec_script.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_tag.c libswfdec/swfdec_text_field.c