[Swfdec-commits] 2 commits - vivified/code

Benjamin Otte company at kemper.freedesktop.org
Thu Jun 26 13:45:44 PDT 2008


 vivified/code/test/compiler/Makefile.am             |    2 
 vivified/code/test/compiler/asm-arguments.as        |    4 +
 vivified/code/test/compiler/asm-arguments.as.expect |   13 +++
 vivified/code/vivi_code_assembler.c                 |   77 ++++++++++++++++++--
 vivified/code/vivi_code_assembler.h                 |    9 ++
 vivified/code/vivi_parser.c                         |   23 +++++
 6 files changed, 120 insertions(+), 8 deletions(-)

New commits:
commit 479a830e17b9e3646c33c373b61fcc8a39613222
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Jun 26 22:16:42 2008 +0200

    add a simple test for asm arguments

diff --git a/vivified/code/test/compiler/Makefile.am b/vivified/code/test/compiler/Makefile.am
index 16c3f79..f63137c 100644
--- a/vivified/code/test/compiler/Makefile.am
+++ b/vivified/code/test/compiler/Makefile.am
@@ -22,6 +22,8 @@ EXTRA_DIST = \
 	array_literal_empty.as.expect \
 	array_literal_missing_values.as \
 	array_literal_missing_values.as.expect \
+	asm-arguments.as \
+	asm-arguments.as.expect \
 	asm_default.as \
 	asm_default.as.expect \
 	asm_empty.as \
diff --git a/vivified/code/test/compiler/asm-arguments.as b/vivified/code/test/compiler/asm-arguments.as
new file mode 100644
index 0000000..a150cda
--- /dev/null
+++ b/vivified/code/test/compiler/asm-arguments.as
@@ -0,0 +1,4 @@
+asm (x, values[y]) {
+  trace
+  trace
+}
diff --git a/vivified/code/test/compiler/asm-arguments.as.expect b/vivified/code/test/compiler/asm-arguments.as.expect
new file mode 100644
index 0000000..7a27d39
--- /dev/null
+++ b/vivified/code/test/compiler/asm-arguments.as.expect
@@ -0,0 +1,13 @@
+asm {
+  pool "x", "values", "y"
+  push pool 0
+  get_variable
+  push pool 1
+  get_variable
+  push pool 2
+  get_variable
+  get_member
+  trace
+  trace
+  end
+}
commit 993413e3e19a0a6957f8f2b6d15b71c0ab2fb0ab
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Jun 26 22:13:13 2008 +0200

    add arguments to the assembler
    
    This allows code such as:
      asm (values[i], "foo") { callfunction };
    instead of having to write lots of push, getvariable statements.
    
    It's also in preparation to move the decompiler to use ViviCodeAssembler.

diff --git a/vivified/code/vivi_code_assembler.c b/vivified/code/vivi_code_assembler.c
index ded99ca..768cab0 100644
--- a/vivified/code/vivi_code_assembler.c
+++ b/vivified/code/vivi_code_assembler.c
@@ -25,13 +25,14 @@
 #include <swfdec/swfdec_script_internal.h>
 
 #include "vivi_code_assembler.h"
+#include "vivi_code_asm_pool.h"
+#include "vivi_code_asm_push.h"
 #include "vivi_code_comment.h"
 #include "vivi_code_compiler.h"
 #include "vivi_code_emitter.h"
 #include "vivi_code_label.h"
 #include "vivi_code_printer.h"
-#include "vivi_code_asm_pool.h"
-#include "vivi_code_asm_push.h"
+#include "vivi_code_undefined.h"
 
 G_DEFINE_TYPE (ViviCodeAssembler, vivi_code_assembler, VIVI_TYPE_CODE_STATEMENT)
 
@@ -39,12 +40,11 @@ static void
 vivi_code_assembler_dispose (GObject *object)
 {
   ViviCodeAssembler *assembler = VIVI_CODE_ASSEMBLER (object);
-  guint i;
 
-  for (i = 0; i < assembler->codes->len; i++) {
-    g_object_unref (g_ptr_array_index (assembler->codes, i));
-  }
+  g_ptr_array_foreach (assembler->codes, (GFunc) g_object_unref, NULL);
   g_ptr_array_free (assembler->codes, TRUE);
+  g_ptr_array_foreach (assembler->arguments, (GFunc) g_object_unref, NULL);
+  g_ptr_array_free (assembler->arguments, TRUE);
 
   G_OBJECT_CLASS (vivi_code_assembler_parent_class)->dispose (object);
 }
@@ -61,7 +61,18 @@ vivi_code_assembler_print (ViviCodeToken *token, ViviCodePrinter *printer)
   ViviCodeAssembler *assembler = VIVI_CODE_ASSEMBLER (token);
   guint i;
 
-  vivi_code_printer_print (printer, "asm {");
+  vivi_code_printer_print (printer, "asm");
+  if (assembler->arguments->len) {
+    vivi_code_printer_print (printer, " (");
+    for (i = 0; i < assembler->codes->len; i++) {
+      if (i > 0)
+	vivi_code_printer_print (printer, ", ");
+      vivi_code_printer_print_value (printer, 
+	  g_ptr_array_index (assembler->arguments, i), VIVI_PRECEDENCE_MEMBER);
+    }
+    vivi_code_printer_print (printer, ")");
+  }
+  vivi_code_printer_print (printer, " {");
   vivi_code_printer_new_line (printer, FALSE);
   vivi_code_printer_push_indentation (printer);
   for (i = 0; i < assembler->codes->len; i++) {
@@ -78,6 +89,11 @@ vivi_code_assembler_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
   ViviCodeAssembler *assembler = VIVI_CODE_ASSEMBLER (token);
   guint i;
 
+  for (i = 0; i < assembler->arguments->len; i++) {
+    vivi_code_compiler_compile_value (compiler, 
+	g_ptr_array_index (assembler->arguments, i));
+  }
+
   // TODO: clone?
   for (i = 0; i < assembler->codes->len; i++) {
     vivi_code_compiler_add_code (compiler,
@@ -103,6 +119,7 @@ vivi_code_assembler_class_init (ViviCodeAssemblerClass *klass)
 static void
 vivi_code_assembler_init (ViviCodeAssembler *assembler)
 {
+  assembler->arguments = g_ptr_array_new ();
   assembler->codes = g_ptr_array_new ();
 }
 
@@ -159,6 +176,50 @@ vivi_code_assembler_remove_code (ViviCodeAssembler *assembler, ViviCodeAsm *code
     g_return_if_reached ();
 }
 
+/*** ARGUMENT HANDLING ***/
+
+guint
+vivi_code_assembler_get_n_arguments (ViviCodeAssembler *assembler)
+{
+  g_return_val_if_fail (VIVI_IS_CODE_ASSEMBLER (assembler), 0);
+
+  return assembler->arguments->len;
+}
+
+void
+vivi_code_assembler_push_argument (ViviCodeAssembler *assembler, ViviCodeValue *value)
+{
+  g_return_if_fail (VIVI_IS_CODE_ASSEMBLER (assembler));
+  g_return_if_fail (VIVI_IS_CODE_VALUE (value));
+
+  g_object_ref (value);
+  g_ptr_array_add (assembler->arguments, value);
+}
+
+ViviCodeValue *
+vivi_code_assembler_pop_argument (ViviCodeAssembler *assembler)
+{
+  g_return_val_if_fail (VIVI_IS_CODE_ASSEMBLER (assembler), NULL);
+
+  if (assembler->arguments->len == 0) {
+    return vivi_code_undefined_new ();
+  } else {
+    return g_ptr_array_remove_index (assembler->arguments, 
+	assembler->arguments->len - 1);
+  }
+}
+
+ViviCodeValue *
+vivi_code_assembler_get_argument (ViviCodeAssembler *assembler, guint i)
+{
+  g_return_val_if_fail (VIVI_IS_CODE_ASSEMBLER (assembler), NULL);
+  g_return_val_if_fail (i < assembler->arguments->len, NULL);
+
+  return g_ptr_array_index (assembler->arguments, i);
+}
+
+/*** OPTIMIZATION ***/
+
 gboolean
 vivi_code_assembler_pool (ViviCodeAssembler *assembler)
 {
@@ -357,6 +418,8 @@ vivi_code_assembler_assemble_script (ViviCodeAssembler *assembler,
   guint i;
 
   g_return_val_if_fail (VIVI_IS_CODE_ASSEMBLER (assembler), NULL);
+  /* FIXME: should this work? */
+  g_return_val_if_fail (assembler->arguments->len == 0, NULL);
 
   emit = vivi_code_emitter_new (version);
   for (i = 0; i < assembler->codes->len; i++) {
diff --git a/vivified/code/vivi_code_assembler.h b/vivified/code/vivi_code_assembler.h
index 67b4124..4b96711 100644
--- a/vivified/code/vivi_code_assembler.h
+++ b/vivified/code/vivi_code_assembler.h
@@ -22,6 +22,7 @@
 
 #include <vivified/code/vivi_code_asm.h>
 #include <vivified/code/vivi_code_statement.h>
+#include <vivified/code/vivi_code_value.h>
 
 G_BEGIN_DECLS
 
@@ -40,6 +41,7 @@ struct _ViviCodeAssembler
   ViviCodeStatement	statement;
 
   GPtrArray *		codes;		/* ViviCodeAsm inside this assembler */
+  GPtrArray *		arguments;	/* ViviCodeValue of values to push on the stack before running the asm */
 };
 
 struct _ViviCodeAssemblerClass
@@ -61,6 +63,13 @@ void			vivi_code_assembler_insert_code  	(ViviCodeAssembler *	assembler,
 void			vivi_code_assembler_remove_code		(ViviCodeAssembler *	assembler,
 								 ViviCodeAsm *		code);
 
+guint			vivi_code_assembler_get_n_arguments	(ViviCodeAssembler *	assembler);
+ViviCodeValue *		vivi_code_assembler_get_argument	(ViviCodeAssembler *	assembler,
+								 guint			i);
+void			vivi_code_assembler_push_argument	(ViviCodeAssembler *	assembler,
+								 ViviCodeValue *	value);
+ViviCodeValue *		vivi_code_assembler_pop_argument	(ViviCodeAssembler *	assembler);
+
 gboolean		vivi_code_assembler_pool		(ViviCodeAssembler *	assembler);
 void			vivi_code_assembler_merge_push		(ViviCodeAssembler *	assembler,
 								 guint			max_depth);
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 1ef1144..bcb5814 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -1422,7 +1422,7 @@ peek_asm_statement (ParseData *data)
 
   value = vivi_parser_scanner_get_value (data->scanner, 2);
 
-  return (value->token == TOKEN_BRACE_LEFT);
+  return (value->token == TOKEN_BRACE_LEFT || value->token == TOKEN_PARENTHESIS_LEFT);
 }
 
 static ViviCodeStatement *
@@ -1435,6 +1435,27 @@ parse_asm_statement (ParseData *data)
 
   if (g_ascii_strcasecmp (parse_identifier_value (data), "asm") != 0)
     vivi_parser_error (data, "Expected 'asm'");
+
+  if (try_parse_token (data, TOKEN_PARENTHESIS_LEFT)) {
+    ViviCodeValue **arguments;
+    guint i;
+
+    if (!try_parse_token (data, TOKEN_PARENTHESIS_RIGHT)) {
+      parse_value_list (data, peek_assignment_expression,
+	  parse_assignment_expression, &arguments, TOKEN_COMMA);
+      parse_token (data, TOKEN_PARENTHESIS_RIGHT);
+    } else {
+      arguments = NULL;
+    }
+
+    if (arguments != NULL) {
+      for (i = 0; arguments[i] != NULL; i++) {
+	vivi_code_assembler_push_argument (assembler, arguments[i]);
+      }
+      free_value_list (arguments);
+    }
+  }
+
   parse_token (data, TOKEN_BRACE_LEFT);
 
   if (!try_parse_token (data, TOKEN_BRACE_RIGHT)) {


More information about the Swfdec-commits mailing list