[Swfdec-commits] 7 commits - vivified/code

Benjamin Otte company at kemper.freedesktop.org
Tue Apr 15 03:19:30 PDT 2008


 vivified/code/decompiler.c                  |   57 ++++++++++++++++++++--------
 vivified/code/test/Makefile.am              |    6 ++
 vivified/code/test/loop-empty.swf           |binary
 vivified/code/test/loop-empty.swf.expect    |    8 +++
 vivified/code/test/loop-empty.xml           |   18 ++++++++
 vivified/code/test/loop-infinite.swf        |binary
 vivified/code/test/loop-infinite.swf.expect |    8 +++
 vivified/code/test/loop-infinite.xml        |   19 +++++++++
 vivified/code/vivi_code_label.c             |    9 ++++
 vivified/code/vivi_code_or.c                |    4 -
 vivified/code/vivi_decompiler.c             |   37 +++++++++++++++---
 11 files changed, 142 insertions(+), 24 deletions(-)

New commits:
commit ed9659e4a240403d0f0e4bd21544c221fc32fa20
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Apr 15 12:16:06 2008 +0200

    add another test for self-referencing blocks

diff --git a/vivified/code/test/Makefile.am b/vivified/code/test/Makefile.am
index e07ecb7..a9f5c2d 100644
--- a/vivified/code/test/Makefile.am
+++ b/vivified/code/test/Makefile.am
@@ -32,6 +32,9 @@ EXTRA_DIST = \
 	loop-empty.swf \
 	loop-empty.swf.expect \
 	loop-empty.xml \
+	loop-infinite.swf \
+	loop-infinite.swf.expect \
+	loop-infinite.xml \
 	loop-nested.as \
 	loop-nested.swf \
 	loop-nested.swf.expect \
diff --git a/vivified/code/test/loop-infinite.swf b/vivified/code/test/loop-infinite.swf
new file mode 100644
index 0000000..6e6a921
Binary files /dev/null and b/vivified/code/test/loop-infinite.swf differ
diff --git a/vivified/code/test/loop-infinite.swf.expect b/vivified/code/test/loop-infinite.swf.expect
new file mode 100644
index 0000000..23e8642
--- /dev/null
+++ b/vivified/code/test/loop-infinite.swf.expect
@@ -0,0 +1,8 @@
+/* version: 7 - size: 200x150 */
+
+/* Sprite0_Frame0 */
+function () {
+  for (;;)
+    trace (undefined);
+}
+
diff --git a/vivified/code/test/loop-infinite.xml b/vivified/code/test/loop-infinite.xml
new file mode 100644
index 0000000..cc216a2
--- /dev/null
+++ b/vivified/code/test/loop-infinite.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+  <!-- swfmill xml2swf loops.xml loops.swf -->
+  <Header framerate="25" frames="1">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <DoAction>
+	<actions>
+	  <Trace />
+	  <BranchAlways byteOffset="65530" />
+	</actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit 67533a145499fdbfa761f03cf6d3b9b5301bfd39
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Apr 15 12:13:52 2008 +0200

    SwfdecDecoder works without a player now!
    
    Which means we can easily decompile infinite loops :)

diff --git a/vivified/code/decompiler.c b/vivified/code/decompiler.c
index 078a3fb..f7fa70e 100644
--- a/vivified/code/decompiler.c
+++ b/vivified/code/decompiler.c
@@ -31,6 +31,33 @@
 #include "vivi_code_function.h"
 #include "vivi_code_text_printer.h"
 
+static SwfdecDecoder *
+swfdec_decoder_new_from_file (const char *filename, GError **error)
+{
+  SwfdecDecoder *dec;
+  SwfdecBuffer *buffer;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+
+  buffer = swfdec_buffer_new_from_file (filename, error);
+  if (buffer == NULL)
+    return NULL;
+
+  dec = swfdec_decoder_new (buffer);
+  if (dec == NULL) {
+    g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOSYS, 
+	"file cannot be decoded by Swfdec");
+    swfdec_buffer_unref (buffer);
+    return NULL;
+  }
+
+  swfdec_decoder_parse (dec, buffer);
+  swfdec_decoder_eof (dec);
+
+  return dec;
+}
+
+
 static void
 decode_script (gpointer scriptp, gpointer unused)
 {
@@ -69,33 +96,31 @@ script_compare (gconstpointer a, gconstpointer b)
 int 
 main (int argc, char *argv[])
 {
-  SwfdecPlayer *player;
   SwfdecSwfDecoder *dec;
-  SwfdecURL *url;
   GList *scripts;
+  GError *error;
 
   if (argc < 2) {
     g_print ("%s FILENAME\n", argv[0]);
     return 1;
   }
 
-  player = swfdec_player_new (NULL);
-  url = swfdec_url_new_from_input (argv[1]);
-  swfdec_player_set_url (player, url);
-  swfdec_url_free (url);
-  /* FIXME: HACK! */
-  swfdec_player_advance (player, 0);
-  if (player->priv->roots == NULL ||
-      !SWFDEC_IS_SPRITE_MOVIE (player->priv->roots->data) ||
-      (dec = SWFDEC_SWF_DECODER (SWFDEC_MOVIE (player->priv->roots->data)->resource->decoder)) == NULL) {
-    g_printerr ("Error parsing file \"%s\"\n", argv[1]);
-    g_object_unref (player);
-    player = NULL;
+  swfdec_init ();
+
+  dec = (SwfdecSwfDecoder *) swfdec_decoder_new_from_file (argv[1], &error);
+  if (dec == NULL) {
+    g_printerr ("%s\n", error->message);
+    g_error_free (error);
+    return 1;
+  }
+  if (!SWFDEC_IS_SWF_DECODER (dec)) {
+    g_printerr ("\"%s\" is not a Flash file.\n", argv[1]);
+    g_object_unref (dec);
     return 1;
   }
 
   g_print ("/* version: %d - size: %ux%u */\n", dec->version,
-      player->priv->width, player->priv->height);
+      SWFDEC_DECODER (dec)->width, SWFDEC_DECODER (dec)->height);
   g_print ("\n");
   scripts = NULL;
   g_hash_table_foreach (dec->scripts, enqueue, &scripts);
@@ -104,7 +129,7 @@ main (int argc, char *argv[])
   g_list_foreach (scripts, decode_script, NULL);
 
   g_list_free (scripts);
-  g_object_unref (player);
+  g_object_unref (dec);
   return 0;
 }
 
commit af8277b32901dce7c13d1ac001ef8af0dbb3cee3
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Apr 15 11:58:41 2008 +0200

    make vivi_code_or_new return a ViviCodeOr

diff --git a/vivified/code/vivi_code_or.c b/vivified/code/vivi_code_or.c
index ae215bf..0a952ae 100644
--- a/vivified/code/vivi_code_or.c
+++ b/vivified/code/vivi_code_or.c
@@ -33,13 +33,13 @@ vivi_code_or_class_init (ViviCodeOrClass *klass)
 
   token_class->compile = NULL; /* FIXME */
 
-  binary_class->operator_name = "&&";
+  binary_class->operator_name = "||";
 }
 
 static void
 vivi_code_or_init (ViviCodeOr *and)
 {
-  vivi_code_value_set_precedence (VIVI_CODE_VALUE (and), VIVI_PRECEDENCE_AND);
+  vivi_code_value_set_precedence (VIVI_CODE_VALUE (and), VIVI_PRECEDENCE_OR);
 }
 
 ViviCodeValue *
commit f64303f0c835e4aa1cd9b534b5e3f9b9b80d8d07
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Apr 15 11:57:53 2008 +0200

    add testcase for the empty loop

diff --git a/vivified/code/test/Makefile.am b/vivified/code/test/Makefile.am
index 3ad5b13..e07ecb7 100644
--- a/vivified/code/test/Makefile.am
+++ b/vivified/code/test/Makefile.am
@@ -29,6 +29,9 @@ EXTRA_DIST = \
 	if-nested.as \
 	if-nested.swf \
 	if-nested.swf.expect \
+	loop-empty.swf \
+	loop-empty.swf.expect \
+	loop-empty.xml \
 	loop-nested.as \
 	loop-nested.swf \
 	loop-nested.swf.expect \
diff --git a/vivified/code/test/loop-empty.swf b/vivified/code/test/loop-empty.swf
new file mode 100644
index 0000000..a8c5a89
Binary files /dev/null and b/vivified/code/test/loop-empty.swf differ
diff --git a/vivified/code/test/loop-empty.swf.expect b/vivified/code/test/loop-empty.swf.expect
new file mode 100644
index 0000000..79326de
--- /dev/null
+++ b/vivified/code/test/loop-empty.swf.expect
@@ -0,0 +1,8 @@
+/* version: 7 - size: 200x150 */
+
+/* Sprite0_Frame0 */
+function () {
+  for (;;)
+    ;
+}
+
diff --git a/vivified/code/test/loop-empty.xml b/vivified/code/test/loop-empty.xml
new file mode 100644
index 0000000..8749ac8
--- /dev/null
+++ b/vivified/code/test/loop-empty.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<swf version="7" compressed="1">
+  <!-- swfmill xml2swf loops.xml loops.swf -->
+  <Header framerate="25" frames="1">
+    <size>
+      <Rectangle left="0" right="4000" top="0" bottom="3000"/>
+    </size>
+    <tags>
+      <DoAction>
+	<actions>
+	  <BranchAlways byteOffset="65531" />
+	</actions>
+      </DoAction>
+      <ShowFrame/>
+      <End/>
+    </tags>
+  </Header>
+</swf>
commit 766259e6bfdf74eb86d2d8cb950e4f69eb518133
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Apr 15 11:55:27 2008 +0200

    decompile self-referencing blocks into loops

diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index ab37c81..108126b 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -1343,11 +1343,12 @@ vivi_decompiler_merge_loops (GList **list)
 	 (vivi_decompiler_block_get_branch (start) &&
 	  vivi_decompiler_block_get_next (start) == end))) {
       if (vivi_decompiler_block_get_branch (start) == end) {
-	ViviCodeValue *value = vivi_code_unary_new (
-	    vivi_decompiler_block_get_branch_condition (start), '!');
-	vivi_code_loop_set_condition (VIVI_CODE_LOOP (loop),
-	    vivi_code_value_optimize (value, SWFDEC_AS_TYPE_BOOLEAN));
+	ViviCodeValue *value, *opt;
+	value = vivi_code_unary_new (vivi_decompiler_block_get_branch_condition (start), '!');
+	opt = vivi_code_value_optimize (value, SWFDEC_AS_TYPE_BOOLEAN);
 	g_object_unref (value);
+	vivi_code_loop_set_condition (VIVI_CODE_LOOP (loop), opt);
+	g_object_unref (opt);
       } else {
 	vivi_code_loop_set_condition (VIVI_CODE_LOOP (loop), 
 	    vivi_decompiler_block_get_branch_condition (start));
@@ -1359,6 +1360,30 @@ vivi_decompiler_merge_loops (GList **list)
 	  vivi_decompiler_block_get_next (start));
       vivi_code_block_add_statement (VIVI_CODE_BLOCK (start), VIVI_CODE_STATEMENT (loop));
       vivi_decompiler_block_set_next (start, end);
+    } else if (start == end) {
+      /* very simple for (;;) loop */
+      g_assert (contained == NULL);
+      contained = g_list_prepend (contained, start);
+      block = vivi_decompiler_block_new (vivi_decompiler_state_copy (
+	    vivi_decompiler_block_get_start_state (start)));
+      vivi_code_block_add_statement (VIVI_CODE_BLOCK (block), VIVI_CODE_STATEMENT (loop));
+      if (vivi_decompiler_block_get_branch (start)) {
+	ViviCodeValue *value, *opt;
+	value = vivi_code_unary_new (vivi_decompiler_block_get_branch_condition (start), '!');
+	opt = vivi_code_value_optimize (value, SWFDEC_AS_TYPE_BOOLEAN);
+	g_object_unref (value);
+	vivi_code_loop_set_condition (VIVI_CODE_LOOP (loop), opt);
+	g_object_unref (opt);
+	vivi_decompiler_block_set_next (block, vivi_decompiler_block_get_branch (start));
+	vivi_decompiler_block_set_branch (start, NULL, NULL);
+      }
+      vivi_decompiler_block_set_next (start, NULL);
+      for (walk2 = *list; walk2; walk2 = walk2->next) {
+	if (walk2->data == start) {
+	  walk2->data = block;
+	  break;
+	}
+      }
     } else {
       /* FIXME: for (;;) loop */
       contained = g_list_prepend (contained, start);
@@ -1380,7 +1405,6 @@ vivi_decompiler_merge_loops (GList **list)
       }
       vivi_decompiler_block_set_next (block, end);
     }
-
     /* break all connections to the outside */
     for (walk2 = contained; walk2; walk2 = walk2->next) {
       block = walk2->data;
@@ -1435,6 +1459,7 @@ vivi_decompiler_merge_loops (GList **list)
       }
     }
     body = VIVI_CODE_BLOCK (vivi_decompiler_merge_blocks (contained, loop_start));
+    /* remove all continue statements at the end */
     while ((len = vivi_code_block_get_n_statements (body))) {
       stmt = vivi_code_block_get_statement (body, len - 1);
       if (VIVI_IS_CODE_CONTINUE (stmt)) {
commit 3984ce1d6cb1d8e276652cf27020b807db284352
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Apr 15 10:40:27 2008 +0200

    labels need braces

diff --git a/vivified/code/vivi_code_label.c b/vivified/code/vivi_code_label.c
index 8f57c38..34cbf4c 100644
--- a/vivified/code/vivi_code_label.c
+++ b/vivified/code/vivi_code_label.c
@@ -54,16 +54,25 @@ vivi_code_label_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
   // TODO: save the position
 }
 
+static gboolean
+vivi_code_label_needs_braces (ViviCodeStatement *stmt)
+{
+  return TRUE;
+}
+
 static void
 vivi_code_label_class_init (ViviCodeLabelClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+  ViviCodeStatementClass *statement_class = VIVI_CODE_STATEMENT_CLASS (klass);
 
   object_class->dispose = vivi_code_label_dispose;
 
   token_class->print = vivi_code_label_print;
   token_class->compile = vivi_code_label_compile;
+
+  statement_class->needs_braces = vivi_code_label_needs_braces;
 }
 
 static void
commit 85568e3d97b15dbe4f04351125265916e3edbae9
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Apr 15 10:37:20 2008 +0200

    a blcok referencing itself is not a line

diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index 53787c0..ab37c81 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -1036,7 +1036,7 @@ vivi_decompiler_merge_lines (GList **list)
       continue;
     /* has no next block */
     next = vivi_decompiler_block_get_next (block);
-    if (next == NULL)
+    if (next == NULL || next == block)
       continue;
     /* The next block has multiple incoming blocks */
     if (vivi_decompiler_block_get_n_incoming (next) != 1)


More information about the Swfdec-commits mailing list