[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