[Swfdec-commits] 8 commits - swfdec/swfdec_bots.c swfdec/swfdec_bots.h vivified/code

Pekka Lampila medar at kemper.freedesktop.org
Tue Apr 8 12:02:00 PDT 2008


 swfdec/swfdec_bots.c                          |   61 +++++++++
 swfdec/swfdec_bots.h                          |   11 +
 vivified/code/vivi_code_assignment.c          |   23 +--
 vivified/code/vivi_code_binary.c              |   16 ++
 vivified/code/vivi_code_break.c               |    8 +
 vivified/code/vivi_code_comment.c             |    8 +
 vivified/code/vivi_code_compiler.c            |  164 ++++++++++++++++++--------
 vivified/code/vivi_code_compiler.h            |   20 ++-
 vivified/code/vivi_code_constant.c            |    2 
 vivified/code/vivi_code_continue.c            |    8 +
 vivified/code/vivi_code_function.c            |   59 +++++++--
 vivified/code/vivi_code_function.h            |    5 
 vivified/code/vivi_code_function_call.c       |   41 ++++++
 vivified/code/vivi_code_get.c                 |   15 +-
 vivified/code/vivi_code_get_url.c             |   24 +++
 vivified/code/vivi_code_if.c                  |   32 ++++-
 vivified/code/vivi_code_init_array.c          |   21 +++
 vivified/code/vivi_code_init_object.c         |   21 +++
 vivified/code/vivi_code_label.c               |    8 +
 vivified/code/vivi_code_return.c              |   12 +
 vivified/code/vivi_code_throw.c               |   14 ++
 vivified/code/vivi_code_trace.c               |    4 
 vivified/code/vivi_code_unary.c               |   14 ++
 vivified/code/vivi_code_value_statement.c     |   13 ++
 vivified/code/vivi_compiler.c                 |   79 ++++++++----
 vivified/code/vivi_compiler_empty_statement.c |    9 +
 vivified/code/vivi_compiler_scanner_lex.l     |    2 
 27 files changed, 572 insertions(+), 122 deletions(-)

New commits:
commit 1c791efc28a201e16aa8cc41cf10181fbd7bf653
Merge: 062b1da... 07c175a...
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue Apr 8 22:01:21 2008 +0300

    Merge branch 'master' of ssh://medar@git.freedesktop.org/git/swfdec/swfdec

commit 062b1da75e84452388fff0c513a9725829c322d3
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue Apr 8 21:55:02 2008 +0300

    Fix wrong offset written to if jump

diff --git a/vivified/code/vivi_code_if.c b/vivified/code/vivi_code_if.c
index 99603ae..4bc5471 100644
--- a/vivified/code/vivi_code_if.c
+++ b/vivified/code/vivi_code_if.c
@@ -140,7 +140,7 @@ vivi_code_if_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
   }
 
   vivi_code_compiler_write_s16 (compiler,
-      vivi_code_compiler_tail_size (compiler) + 4); // else_statement + jump
+      vivi_code_compiler_tail_size (compiler) + 5); // else_statement + jump
   vivi_code_compiler_end_action (compiler);
 
   vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_JUMP);
commit 84bd2eb15261a45132b7d9087b112d67e0978154
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue Apr 8 21:40:33 2008 +0300

    Implement/fix compile vfunc for bunch of ViviCode classes

diff --git a/vivified/code/vivi_code_assignment.c b/vivified/code/vivi_code_assignment.c
index 104eaee..1045031 100644
--- a/vivified/code/vivi_code_assignment.c
+++ b/vivified/code/vivi_code_assignment.c
@@ -95,14 +95,11 @@ static void
 vivi_code_assignment_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 {
   ViviCodeAssignment *assignment = VIVI_CODE_ASSIGNMENT (token);
+  SwfdecAsAction action;
 
-  if (assignment->local) {
-    vivi_code_compiler_add_action (compiler, SWFDEC_AS_ACTION_DEFINE_LOCAL);
-  } else if (assignment->from) {
-    vivi_code_compiler_add_action (compiler, SWFDEC_AS_ACTION_SET_MEMBER);
-  } else {
-    vivi_code_compiler_add_action (compiler, SWFDEC_AS_ACTION_SET_VARIABLE);
-  }
+  vivi_code_compiler_compile_value (compiler, assignment->name);
+  if (assignment->from && !assignment->local)
+    vivi_code_compiler_compile_value (compiler, assignment->from);
 
   if (assignment->local && assignment->from) {
     ViviCodeValue *get =
@@ -113,11 +110,15 @@ vivi_code_assignment_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
     vivi_code_compiler_compile_value (compiler, assignment->value);
   }
 
-  vivi_code_compiler_compile_value (compiler, assignment->name);
-  if (assignment->from && !assignment->local)
-    vivi_code_compiler_compile_value (compiler, assignment->from);
 
-  vivi_code_compiler_end_action (compiler);
+  if (assignment->local) {
+    action = SWFDEC_AS_ACTION_DEFINE_LOCAL;
+  } else if (assignment->from) {
+    action = SWFDEC_AS_ACTION_SET_MEMBER;
+  } else {
+    action = SWFDEC_AS_ACTION_SET_VARIABLE;
+  }
+  vivi_code_compiler_write_empty_action (compiler, action);
 }
 
 static void
diff --git a/vivified/code/vivi_code_binary.c b/vivified/code/vivi_code_binary.c
index 1b69476..ec78597 100644
--- a/vivified/code/vivi_code_binary.c
+++ b/vivified/code/vivi_code_binary.c
@@ -25,6 +25,7 @@
 
 #include "vivi_code_binary.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 static struct {
   const char *		operation;
@@ -84,6 +85,20 @@ vivi_code_binary_print (ViviCodeToken *token, ViviCodePrinter*printer)
       operation_table[binary->operation_index].precedence);
 }
 
+static void
+vivi_code_binary_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeBinary *binary = VIVI_CODE_BINARY (token);
+
+  g_assert (operation_table[binary->operation_index].bytecode != 0);
+
+  vivi_code_compiler_compile_value (compiler, binary->left);
+  vivi_code_compiler_compile_value (compiler, binary->right);
+
+  vivi_code_compiler_write_empty_action (compiler,
+      operation_table[binary->operation_index].bytecode);
+}
+
 static gboolean
 vivi_code_binary_is_constant (ViviCodeValue *value)
 {
@@ -103,6 +118,7 @@ vivi_code_binary_class_init (ViviCodeBinaryClass *klass)
   object_class->dispose = vivi_code_binary_dispose;
 
   token_class->print = vivi_code_binary_print;
+  token_class->compile = vivi_code_binary_compile;
 
   value_class->is_constant = vivi_code_binary_is_constant;
 }
diff --git a/vivified/code/vivi_code_break.c b/vivified/code/vivi_code_break.c
index 79e8b6c..9286fa5 100644
--- a/vivified/code/vivi_code_break.c
+++ b/vivified/code/vivi_code_break.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_break.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeBreak, vivi_code_break, VIVI_TYPE_CODE_STATEMENT)
 
@@ -34,11 +35,18 @@ vivi_code_break_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_break_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  g_printerr ("Implement break\n");
+}
+
+static void
 vivi_code_break_class_init (ViviCodeBreakClass *klass)
 {
   ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
 
   token_class->print = vivi_code_break_print;
+  token_class->compile = vivi_code_break_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_code_comment.c b/vivified/code/vivi_code_comment.c
index 83cdfd8..251bc2a 100644
--- a/vivified/code/vivi_code_comment.c
+++ b/vivified/code/vivi_code_comment.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_comment.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeComment, vivi_code_comment, VIVI_TYPE_CODE_STATEMENT)
 
@@ -48,6 +49,12 @@ vivi_code_comment_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_comment_compile (ViviCodeToken *token, ViviCodeCompiler *compile)
+{
+  /* nothing */
+}
+
+static void
 vivi_code_comment_class_init (ViviCodeCommentClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -56,6 +63,7 @@ vivi_code_comment_class_init (ViviCodeCommentClass *klass)
   object_class->dispose = vivi_code_comment_dispose;
 
   token_class->print = vivi_code_comment_print;
+  token_class->compile = vivi_code_comment_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_code_constant.c b/vivified/code/vivi_code_constant.c
index 2bf3fcf..5fd6519 100644
--- a/vivified/code/vivi_code_constant.c
+++ b/vivified/code/vivi_code_constant.c
@@ -124,7 +124,7 @@ vivi_code_constant_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 {
   ViviCodeConstant *constant = VIVI_CODE_CONSTANT (token);
 
-  vivi_code_compiler_add_action (compiler, SWFDEC_AS_ACTION_PUSH);
+  vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_PUSH);
 
   switch (constant->value.type) {
     case SWFDEC_AS_TYPE_UNDEFINED:
diff --git a/vivified/code/vivi_code_continue.c b/vivified/code/vivi_code_continue.c
index 9464836..cb6ab77 100644
--- a/vivified/code/vivi_code_continue.c
+++ b/vivified/code/vivi_code_continue.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_continue.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeContinue, vivi_code_continue, VIVI_TYPE_CODE_STATEMENT)
 
@@ -34,11 +35,18 @@ vivi_code_continue_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_continue_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  g_printerr ("Implement continue\n");
+}
+
+static void
 vivi_code_continue_class_init (ViviCodeContinueClass *klass)
 {
   ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
 
   token_class->print = vivi_code_continue_print;
+  token_class->compile = vivi_code_continue_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_code_function.c b/vivified/code/vivi_code_function.c
index 518f60c..82ae90c 100644
--- a/vivified/code/vivi_code_function.c
+++ b/vivified/code/vivi_code_function.c
@@ -26,6 +26,7 @@
 #include "vivi_code_function.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 #include "vivi_decompiler.h"
 
@@ -35,10 +36,16 @@ static void
 vivi_code_function_dispose (GObject *object)
 {
   ViviCodeFunction *function = VIVI_CODE_FUNCTION (object);
+  guint i;
 
   if (function->body)
     g_object_unref (function->body);
 
+  for (i = 0; i < function->arguments->len; i++) {
+    g_free (g_ptr_array_index (function->arguments, i));
+  }
+  g_ptr_array_free (function->arguments, TRUE);
+
   G_OBJECT_CLASS (vivi_code_function_parent_class)->dispose (object);
 }
 
@@ -49,11 +56,11 @@ vivi_code_function_print (ViviCodeToken *token, ViviCodePrinter*printer)
   guint i;
 
   vivi_code_printer_print (printer, "function (");
-  for (i = 0; i < function->n_arguments; i++) {
+  for (i = 0; i < function->arguments->len; i++) {
     if (i != 0)
       vivi_code_printer_print (printer, ", ");
-    vivi_code_printer_print_token (printer,
-	VIVI_CODE_TOKEN (&function->arguments[i]));
+    vivi_code_printer_print (printer,
+	g_ptr_array_index (function->arguments, i));
   }
   vivi_code_printer_print (printer, ") {");
   vivi_code_printer_new_line (printer, FALSE);
@@ -65,6 +72,37 @@ vivi_code_function_print (ViviCodeToken *token, ViviCodePrinter*printer)
   vivi_code_printer_print (printer, "}");
 }
 
+static void
+vivi_code_function_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeFunction *function = VIVI_CODE_FUNCTION (token);
+  guint i;
+
+  vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_DEFINE_FUNCTION2);
+
+  vivi_code_compiler_write_string (compiler, "");
+  vivi_code_compiler_write_u16 (compiler, function->arguments->len);
+  vivi_code_compiler_write_u8 (compiler, 0);  // reg
+  vivi_code_compiler_write_u16 (compiler, 0);  // flags
+
+  // arguments
+  for (i = 0; i < function->arguments->len; i++) {
+    vivi_code_compiler_write_u8 (compiler, 0);  // register
+    vivi_code_compiler_write_string (compiler,
+	g_ptr_array_index (function->arguments, i )); // name
+  }
+
+  if (function->body != NULL) {
+    vivi_code_compiler_compile_token (compiler,
+	VIVI_CODE_TOKEN (function->body));
+  }
+
+  vivi_code_compiler_write_u16 (compiler,
+      vivi_code_compiler_tail_size (compiler)); // body length
+
+  vivi_code_compiler_end_action (compiler);
+}
+
 static gboolean
 vivi_code_function_is_constant (ViviCodeValue *value)
 {
@@ -81,6 +119,7 @@ vivi_code_function_class_init (ViviCodeFunctionClass *klass)
   object_class->dispose = vivi_code_function_dispose;
 
   token_class->print = vivi_code_function_print;
+  token_class->compile = vivi_code_function_compile;
 
   value_class->is_constant = vivi_code_function_is_constant;
 }
@@ -91,6 +130,8 @@ vivi_code_function_init (ViviCodeFunction *function)
   ViviCodeValue *value = VIVI_CODE_VALUE (function);
 
   vivi_code_value_set_precedence (value, VIVI_PRECEDENCE_CALL);
+
+  function->arguments = g_ptr_array_new ();
 }
 
 ViviCodeValue *
@@ -110,13 +151,12 @@ vivi_code_function_set_body (ViviCodeFunction *function,
 }
 
 void
-vivi_code_function_add_argument (ViviCodeFunction *function,
-    ViviCodeValue *argument)
+vivi_code_function_add_argument (ViviCodeFunction *function, const char *name)
 {
   g_return_if_fail (VIVI_IS_CODE_FUNCTION (function));
-  g_return_if_fail (VIVI_IS_CODE_VALUE (argument));
+  g_return_if_fail (name != NULL);
 
-  // TODO
+  g_ptr_array_add (function->arguments, g_strdup (name));
 }
 
 ViviCodeValue *
@@ -131,10 +171,7 @@ vivi_code_function_new_from_script (SwfdecScript *script)
   function->body = vivi_decompile_script (script);
 
   for (i = 0; i < script->n_arguments; i++) {
-    ViviCodeValue *argument =
-      vivi_code_constant_new_string (script->arguments[i].name);
-    vivi_code_function_add_argument (function, argument);
-    g_object_unref (argument);
+    vivi_code_function_add_argument (function, script->arguments[i].name);
   }
 
   return VIVI_CODE_VALUE (function);
diff --git a/vivified/code/vivi_code_function.h b/vivified/code/vivi_code_function.h
index 00c1dc1..221da93 100644
--- a/vivified/code/vivi_code_function.h
+++ b/vivified/code/vivi_code_function.h
@@ -40,8 +40,7 @@ struct _ViviCodeFunction
 {
   ViviCodeValue		value;
 
-  guint			n_arguments;  		/* number of arguments */
-  ViviCodeValue *	arguments;		/* arguments or NULL if none */
+  GPtrArray *		arguments;		// char *
   ViviCodeStatement *	body;
 };
 
@@ -58,7 +57,7 @@ ViviCodeValue *		vivi_code_function_new_from_script (SwfdecScript *	script);
 void			vivi_code_function_set_body	(ViviCodeFunction *	function,
 							 ViviCodeStatement *	body);
 void			vivi_code_function_add_argument	(ViviCodeFunction *	function,
-							 ViviCodeValue *	argument);
+							 const char *		name);
 
 
 G_END_DECLS
diff --git a/vivified/code/vivi_code_function_call.c b/vivified/code/vivi_code_function_call.c
index 3964f5a..2b8b974 100644
--- a/vivified/code/vivi_code_function_call.c
+++ b/vivified/code/vivi_code_function_call.c
@@ -24,6 +24,7 @@
 #include "vivi_code_function_call.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeFunctionCall, vivi_code_function_call, VIVI_TYPE_CODE_VALUE)
 
@@ -119,6 +120,45 @@ vivi_code_function_call_print (ViviCodeToken *token, ViviCodePrinter*printer)
   vivi_code_printer_print (printer, ")");
 }
 
+static void
+vivi_code_function_call_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeFunctionCall *call = VIVI_CODE_FUNCTION_CALL (token);
+  SwfdecAsAction action;
+  ViviCodeValue *count;
+  guint i;
+
+  for (i = 0; i < call->arguments->len; i++) {
+    vivi_code_compiler_compile_value (compiler,
+	g_ptr_array_index (call->arguments, i));
+  }
+  count = vivi_code_constant_new_number (call->arguments->len);
+  vivi_code_compiler_compile_value (compiler, count);
+  g_object_unref (count);
+
+  vivi_code_compiler_compile_value (compiler, call->name);
+
+  if (call->value)
+    vivi_code_compiler_compile_value (compiler, call->value);
+
+  if (call->construct) {
+    if (call->value) {
+      action = SWFDEC_AS_ACTION_NEW_METHOD;
+    } else {
+      action = SWFDEC_AS_ACTION_NEW_OBJECT;
+    }
+  } else {
+    if (call->value) {
+      action = SWFDEC_AS_ACTION_CALL_METHOD;
+    } else {
+      action = SWFDEC_AS_ACTION_CALL_FUNCTION;
+    }
+  }
+
+  vivi_code_compiler_write_empty_action (compiler, action);
+}
+
 static gboolean
 vivi_code_function_call_is_constant (ViviCodeValue *value)
 {
@@ -135,6 +175,7 @@ vivi_code_function_call_class_init (ViviCodeFunctionCallClass *klass)
   object_class->dispose = vivi_code_function_call_dispose;
 
   token_class->print = vivi_code_function_call_print;
+  token_class->compile = vivi_code_function_call_compile;
 
   value_class->is_constant = vivi_code_function_call_is_constant;
   value_class->optimize = vivi_code_function_call_optimize;
diff --git a/vivified/code/vivi_code_get.c b/vivified/code/vivi_code_get.c
index 687274c..787c822 100644
--- a/vivified/code/vivi_code_get.c
+++ b/vivified/code/vivi_code_get.c
@@ -77,18 +77,19 @@ static void
 vivi_code_get_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 {
   ViviCodeGet *get = VIVI_CODE_GET (token);
-
-  if (get->from) {
-    vivi_code_compiler_add_action (compiler, SWFDEC_AS_ACTION_GET_MEMBER);
-  } else {
-    vivi_code_compiler_add_action (compiler, SWFDEC_AS_ACTION_GET_VARIABLE);
-  }
+  SwfdecAsAction action;
 
   vivi_code_compiler_compile_value (compiler, get->name);
   if (get->from)
     vivi_code_compiler_compile_value (compiler, get->from);
 
-  vivi_code_compiler_end_action (compiler);
+  if (get->from) {
+    action = SWFDEC_AS_ACTION_GET_MEMBER;
+  } else {
+    action = SWFDEC_AS_ACTION_GET_VARIABLE;
+  }
+
+  vivi_code_compiler_write_empty_action (compiler, action);
 }
 
 static gboolean
diff --git a/vivified/code/vivi_code_get_url.c b/vivified/code/vivi_code_get_url.c
index 20a12a1..d9723c4 100644
--- a/vivified/code/vivi_code_get_url.c
+++ b/vivified/code/vivi_code_get_url.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_get_url.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeGetUrl, vivi_code_get_url, VIVI_TYPE_CODE_STATEMENT)
 
@@ -61,6 +62,28 @@ vivi_code_get_url_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_get_url_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeGetUrl *url = VIVI_CODE_GET_URL (token);
+  guint bits;
+
+  vivi_code_compiler_compile_value (compiler, url->target);
+  vivi_code_compiler_compile_value (compiler, url->url);
+
+  vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_GET_URL2);
+
+  bits = url->method;
+  if (url->internal)
+    bits |= 64;
+  if (url->variables)
+    bits |= 128;
+
+  vivi_code_compiler_write_u8 (compiler, bits);
+
+  vivi_code_compiler_end_action (compiler);
+}
+
+static void
 vivi_code_get_url_class_init (ViviCodeGetUrlClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -69,6 +92,7 @@ vivi_code_get_url_class_init (ViviCodeGetUrlClass *klass)
   object_class->dispose = vivi_code_get_url_dispose;
 
   token_class->print = vivi_code_get_url_print;
+  token_class->compile = vivi_code_get_url_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_code_if.c b/vivified/code/vivi_code_if.c
index 07880dc..99603ae 100644
--- a/vivified/code/vivi_code_if.c
+++ b/vivified/code/vivi_code_if.c
@@ -22,8 +22,9 @@
 #endif
 
 #include "vivi_code_if.h"
-#include "vivi_code_printer.h"
 #include "vivi_code_unary.h"
+#include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeIf, vivi_code_if, VIVI_TYPE_CODE_STATEMENT)
 
@@ -125,6 +126,34 @@ vivi_code_if_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_if_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeIf *stmt = VIVI_CODE_IF (token);
+
+  vivi_code_compiler_compile_value (compiler, stmt->condition);
+
+  vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_IF);
+
+  if (stmt->else_statement) {
+    vivi_code_compiler_compile_token (compiler,
+	VIVI_CODE_TOKEN (stmt->else_statement));
+  }
+
+  vivi_code_compiler_write_s16 (compiler,
+      vivi_code_compiler_tail_size (compiler) + 4); // else_statement + jump
+  vivi_code_compiler_end_action (compiler);
+
+  vivi_code_compiler_begin_action (compiler, SWFDEC_AS_ACTION_JUMP);
+
+  vivi_code_compiler_compile_token (compiler,
+      VIVI_CODE_TOKEN (stmt->if_statement));
+
+  vivi_code_compiler_write_s16 (compiler,
+      vivi_code_compiler_tail_size (compiler)); // if_statement
+  vivi_code_compiler_end_action (compiler);
+}
+
+static void
 vivi_code_if_class_init (ViviCodeIfClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -134,6 +163,7 @@ vivi_code_if_class_init (ViviCodeIfClass *klass)
   object_class->dispose = vivi_code_if_dispose;
 
   token_class->print = vivi_code_if_print;
+  token_class->compile = vivi_code_if_compile;
 
   statement_class->optimize = vivi_code_if_optimize;
   statement_class->needs_braces = vivi_code_if_needs_braces;
diff --git a/vivified/code/vivi_code_init_array.c b/vivified/code/vivi_code_init_array.c
index d5ac090..ec73801 100644
--- a/vivified/code/vivi_code_init_array.c
+++ b/vivified/code/vivi_code_init_array.c
@@ -25,6 +25,7 @@
 #include "vivi_code_init_array.h"
 #include "vivi_code_constant.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeInitArray, vivi_code_init_array, VIVI_TYPE_CODE_VALUE)
 
@@ -78,6 +79,25 @@ vivi_code_init_array_print (ViviCodeToken *token, ViviCodePrinter *printer)
   vivi_code_printer_print (printer, "]");
 }
 
+static void
+vivi_code_init_array_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeInitArray *array = VIVI_CODE_INIT_ARRAY (token);
+  ViviCodeValue *count;
+  guint i;
+
+  for (i = 0; i < array->variables->len; i++) {
+    vivi_code_compiler_compile_value (compiler,
+	VIVI_CODE_VALUE (g_ptr_array_index (array->variables, i)));
+  }
+  count = vivi_code_constant_new_number (array->variables->len);
+  vivi_code_compiler_compile_value (compiler, count);
+  g_object_unref (count);
+
+  vivi_code_compiler_write_empty_action (compiler,
+      SWFDEC_AS_ACTION_INIT_ARRAY);
+}
+
 static gboolean
 vivi_code_init_array_is_constant (ViviCodeValue *value)
 {
@@ -95,6 +115,7 @@ vivi_code_init_array_class_init (ViviCodeInitArrayClass *klass)
   object_class->dispose = vivi_code_init_array_dispose;
 
   token_class->print = vivi_code_init_array_print;
+  token_class->compile = vivi_code_init_array_compile;
 
   value_class->is_constant = vivi_code_init_array_is_constant;
   value_class->optimize = vivi_code_init_array_optimize;
diff --git a/vivified/code/vivi_code_init_object.c b/vivified/code/vivi_code_init_object.c
index 4582b44..90c1da3 100644
--- a/vivified/code/vivi_code_init_object.c
+++ b/vivified/code/vivi_code_init_object.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_init_object.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeInitObject, vivi_code_init_object, VIVI_TYPE_CODE_VALUE)
 
@@ -75,6 +76,25 @@ vivi_code_init_object_print (ViviCodeToken *token, ViviCodePrinter*printer)
   vivi_code_printer_print (printer, "}");
 }
 
+static void
+vivi_code_init_object_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeInitObject *object = VIVI_CODE_INIT_OBJECT (token);
+  guint i;
+
+  for (i = 0; i < object->variables->len; i++) {
+    VariableEntry *entry = &g_array_index (object->variables, VariableEntry, i);
+    vivi_code_compiler_compile_value (compiler, entry->value);
+    vivi_code_compiler_compile_value (compiler, entry->name);
+  }
+
+  vivi_code_compiler_write_u8 (compiler, object->variables->len);
+
+  vivi_code_compiler_write_empty_action (compiler,
+      SWFDEC_AS_ACTION_INIT_OBJECT);
+}
+
 static gboolean
 vivi_code_init_object_is_constant (ViviCodeValue *value)
 {
@@ -92,6 +112,7 @@ vivi_code_init_object_class_init (ViviCodeInitObjectClass *klass)
   object_class->dispose = vivi_code_init_object_dispose;
 
   token_class->print = vivi_code_init_object_print;
+  token_class->compile = vivi_code_init_object_compile;
 
   value_class->is_constant = vivi_code_init_object_is_constant;
   value_class->optimize = vivi_code_init_object_optimize;
diff --git a/vivified/code/vivi_code_label.c b/vivified/code/vivi_code_label.c
index d84a9ad..8f57c38 100644
--- a/vivified/code/vivi_code_label.c
+++ b/vivified/code/vivi_code_label.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_label.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeLabel, vivi_code_label, VIVI_TYPE_CODE_STATEMENT)
 
@@ -48,6 +49,12 @@ vivi_code_label_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_label_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  // TODO: save the position
+}
+
+static void
 vivi_code_label_class_init (ViviCodeLabelClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -56,6 +63,7 @@ vivi_code_label_class_init (ViviCodeLabelClass *klass)
   object_class->dispose = vivi_code_label_dispose;
 
   token_class->print = vivi_code_label_print;
+  token_class->compile = vivi_code_label_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_code_return.c b/vivified/code/vivi_code_return.c
index 2bc68f2..629c569 100644
--- a/vivified/code/vivi_code_return.c
+++ b/vivified/code/vivi_code_return.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_return.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeReturn, vivi_code_return, VIVI_TYPE_CODE_STATEMENT)
 
@@ -54,6 +55,16 @@ vivi_code_return_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_return_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeReturn *ret = VIVI_CODE_RETURN (token);
+
+  vivi_code_compiler_compile_value (compiler, ret->value);
+
+  vivi_code_compiler_write_empty_action (compiler, SWFDEC_AS_ACTION_RETURN);
+}
+
+static void
 vivi_code_return_class_init (ViviCodeReturnClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -62,6 +73,7 @@ vivi_code_return_class_init (ViviCodeReturnClass *klass)
   object_class->dispose = vivi_code_return_dispose;
 
   token_class->print = vivi_code_return_print;
+  token_class->compile = vivi_code_return_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_code_throw.c b/vivified/code/vivi_code_throw.c
index ba97115..e805039 100644
--- a/vivified/code/vivi_code_throw.c
+++ b/vivified/code/vivi_code_throw.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_throw.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeThrow, vivi_code_throw, VIVI_TYPE_CODE_STATEMENT)
 
@@ -54,6 +55,18 @@ vivi_code_throw_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_throw_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeThrow *throw_ = VIVI_CODE_THROW (token);
+
+  g_return_if_fail (throw_->value != NULL);
+
+  vivi_code_compiler_compile_value (compiler, throw_->value);
+
+  vivi_code_compiler_write_empty_action (compiler, SWFDEC_AS_ACTION_THROW);
+}
+
+static void
 vivi_code_throw_class_init (ViviCodeThrowClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -62,6 +75,7 @@ vivi_code_throw_class_init (ViviCodeThrowClass *klass)
   object_class->dispose = vivi_code_throw_dispose;
 
   token_class->print = vivi_code_throw_print;
+  token_class->compile = vivi_code_throw_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_code_trace.c b/vivified/code/vivi_code_trace.c
index 4f6b097..b8ced24 100644
--- a/vivified/code/vivi_code_trace.c
+++ b/vivified/code/vivi_code_trace.c
@@ -53,11 +53,9 @@ vivi_code_trace_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
 {
   ViviCodeTrace *trace = VIVI_CODE_TRACE (token);
 
-  vivi_code_compiler_add_action (compiler, SWFDEC_AS_ACTION_TRACE);
-
   vivi_code_compiler_compile_value (compiler, trace->value);
 
-  vivi_code_compiler_end_action (compiler);
+  vivi_code_compiler_write_empty_action (compiler, SWFDEC_AS_ACTION_TRACE);
 }
 
 static void
diff --git a/vivified/code/vivi_code_unary.c b/vivified/code/vivi_code_unary.c
index 9e50338..eb49c45 100644
--- a/vivified/code/vivi_code_unary.c
+++ b/vivified/code/vivi_code_unary.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_unary.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeUnary, vivi_code_unary, VIVI_TYPE_CODE_VALUE)
 
@@ -66,6 +67,18 @@ vivi_code_unary_print (ViviCodeToken *token, ViviCodePrinter*printer)
   vivi_code_printer_print_value (printer, unary->value, VIVI_PRECEDENCE_UNARY);
 }
 
+static void
+vivi_code_unary_compile (ViviCodeToken *token, ViviCodeCompiler *compiler)
+{
+  ViviCodeUnary *unary = VIVI_CODE_UNARY (token);
+
+  g_return_if_fail (unary->operation != '!');
+
+  vivi_code_compiler_compile_value (compiler, unary->value);
+
+  vivi_code_compiler_write_empty_action (compiler, SWFDEC_AS_ACTION_NOT);
+}
+
 static gboolean
 vivi_code_unary_is_constant (ViviCodeValue *value)
 {
@@ -82,6 +95,7 @@ vivi_code_unary_class_init (ViviCodeUnaryClass *klass)
   object_class->dispose = vivi_code_unary_dispose;
 
   token_class->print = vivi_code_unary_print;
+  token_class->compile = vivi_code_unary_compile;
 
   value_class->is_constant = vivi_code_unary_is_constant;
   value_class->optimize = vivi_code_unary_optimize;
diff --git a/vivified/code/vivi_code_value_statement.c b/vivified/code/vivi_code_value_statement.c
index 7677179..97677cb 100644
--- a/vivified/code/vivi_code_value_statement.c
+++ b/vivified/code/vivi_code_value_statement.c
@@ -23,6 +23,7 @@
 
 #include "vivi_code_value_statement.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCodeValueStatement, vivi_code_value_statement, VIVI_TYPE_CODE_STATEMENT)
 
@@ -47,6 +48,17 @@ vivi_code_value_statement_print (ViviCodeToken *token, ViviCodePrinter *printer)
 }
 
 static void
+vivi_code_value_statement_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compiler)
+{
+  ViviCodeValueStatement *stmt = VIVI_CODE_VALUE_STATEMENT (token);
+
+  vivi_code_compiler_compile_value (compiler, stmt->value);
+
+  vivi_code_compiler_write_empty_action (compiler, SWFDEC_AS_ACTION_POP);
+}
+
+static void
 vivi_code_value_statement_class_init (ViviCodeValueStatementClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -55,6 +67,7 @@ vivi_code_value_statement_class_init (ViviCodeValueStatementClass *klass)
   object_class->dispose = vivi_code_value_statement_dispose;
 
   token_class->print = vivi_code_value_statement_print;
+  token_class->compile = vivi_code_value_statement_compile;
 }
 
 static void
diff --git a/vivified/code/vivi_compiler_empty_statement.c b/vivified/code/vivi_compiler_empty_statement.c
index 568da2d..5924234 100644
--- a/vivified/code/vivi_compiler_empty_statement.c
+++ b/vivified/code/vivi_compiler_empty_statement.c
@@ -24,6 +24,7 @@
 
 #include "vivi_compiler_empty_statement.h"
 #include "vivi_code_printer.h"
+#include "vivi_code_compiler.h"
 
 G_DEFINE_TYPE (ViviCompilerEmptyStatement, vivi_compiler_empty_statement, VIVI_TYPE_CODE_STATEMENT)
 
@@ -42,6 +43,13 @@ vivi_compiler_empty_statement_print (ViviCodeToken *token,
 }
 
 static void
+vivi_compiler_empty_statement_compile (ViviCodeToken *token,
+    ViviCodeCompiler *compile)
+{
+  /* nothing */
+}
+
+static void
 vivi_compiler_empty_statement_class_init (
     ViviCompilerEmptyStatementClass *klass)
 {
@@ -49,6 +57,7 @@ vivi_compiler_empty_statement_class_init (
   ViviCodeStatementClass *statement_class = VIVI_CODE_STATEMENT_CLASS (klass);
 
   token_class->print = vivi_compiler_empty_statement_print;
+  token_class->compile = vivi_compiler_empty_statement_compile;
 
   statement_class->optimize = vivi_compiler_empty_statement_optimize;
 }
commit 0faf572681ee9de2ebf96792afac27b68ced9a04
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue Apr 8 21:38:03 2008 +0300

    Parse function arguments

diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index e9696b0..10b3e61 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -2030,6 +2030,7 @@ parse_function_definition (ParseData *data, ViviCodeValue **function,
   ParseStatus status;
   ViviCodeValue **arguments;
   ViviCodeStatement *body;
+  guint i;
 
   *function = NULL;
   *identifier = NULL;
@@ -2098,10 +2099,18 @@ parse_function_definition (ParseData *data, ViviCodeValue **function,
   }
 
   *function = vivi_code_function_new ();
-  vivi_code_function_set_body (VIVI_CODE_FUNCTION (*function), body);
-  if (arguments != NULL)
+  if (body != NULL) {
+    vivi_code_function_set_body (VIVI_CODE_FUNCTION (*function), body);
+    g_object_unref (body);
+  }
+  if (arguments != NULL) {
+    for (i = 0; arguments[i] != NULL; i++) {
+      vivi_code_function_add_argument (VIVI_CODE_FUNCTION (*function),
+	  vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (
+	      VIVI_CODE_GET (arguments[i])->name)));
+    }
     free_value_list (arguments);
-  g_object_unref (body);
+  }
 
   return STATUS_OK;
 }
commit afaade522a4c1e849a6d6cd94fa789e9f2811550
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue Apr 8 21:37:28 2008 +0300

    Fix a warning in the lex code

diff --git a/vivified/code/vivi_compiler_scanner_lex.l b/vivified/code/vivi_compiler_scanner_lex.l
index 10167f5..7d2cc9b 100644
--- a/vivified/code/vivi_compiler_scanner_lex.l
+++ b/vivified/code/vivi_compiler_scanner_lex.l
@@ -33,7 +33,7 @@ identifier_part		[$_a-zA-Z0-9]
 
 %%
 
-			GString *string;
+			GString *string = NULL;
 
 <<EOF>>			{ return TOKEN_EOF; }
 
commit 8987e2917c1e8600ceba4419fac33814343c6349
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue Apr 8 21:37:04 2008 +0300

    Rework ViviCodeCompiler

diff --git a/vivified/code/vivi_code_compiler.c b/vivified/code/vivi_code_compiler.c
index c2370ea..e913e79 100644
--- a/vivified/code/vivi_code_compiler.c
+++ b/vivified/code/vivi_code_compiler.c
@@ -31,12 +31,11 @@ vivi_code_compiler_dispose (GObject *object)
   ViviCodeCompiler *compiler = VIVI_CODE_COMPILER (object);
   GSList *iter;
 
-  if (compiler->data)
-    swfdec_buffer_unref (swfdec_bots_close (compiler->data));
-
   for (iter = compiler->actions; iter != NULL; iter = iter->next) {
-    swfdec_buffer_unref (
-	swfdec_bots_close (((ViviCodeCompilerAction *)iter->data)->data));
+    if (((ViviCodeCompilerAction *)iter->data)->data != NULL) {
+      swfdec_buffer_unref (
+	  swfdec_bots_close (((ViviCodeCompilerAction *)iter->data)->data));
+    }
   }
 
   g_slist_free (compiler->actions);
@@ -55,7 +54,6 @@ vivi_code_compiler_class_init (ViviCodeCompilerClass *klass)
 static void
 vivi_code_compiler_init (ViviCodeCompiler *compiler)
 {
-  compiler->data = swfdec_bots_open ();
 }
 
 ViviCodeCompiler *
@@ -64,36 +62,25 @@ vivi_code_compiler_new (void)
   return g_object_new (VIVI_TYPE_CODE_COMPILER, NULL);
 }
 
-SwfdecBuffer *
-vivi_code_compiler_get_data (ViviCodeCompiler *compiler)
-{
-  SwfdecBuffer *buffer;
-
-  g_return_val_if_fail (VIVI_IS_CODE_COMPILER (compiler), NULL);
-  g_return_val_if_fail (compiler->action == NULL, NULL);
-
-  buffer = swfdec_bots_close (compiler->data);
-  compiler->data = swfdec_bots_open ();
-
-  return buffer;
-}
-
 void
 vivi_code_compiler_compile_token (ViviCodeCompiler *compiler,
     ViviCodeToken *token)
 {
   ViviCodeTokenClass *klass;
   ViviCodeCompilerAction *action;
+  GSList *current;
 
   g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
   g_return_if_fail (VIVI_IS_CODE_TOKEN (token));
 
+  current = compiler->current;
   action = compiler->action;
 
   klass = VIVI_CODE_TOKEN_GET_CLASS (token);
   g_return_if_fail (klass->compile);
   klass->compile (token, compiler);
 
+  g_assert (compiler->current == current);
   g_assert (compiler->action == action);
 }
 
@@ -104,51 +91,119 @@ vivi_code_compiler_compile_value (ViviCodeCompiler *compiler,
   vivi_code_compiler_compile_token (compiler, VIVI_CODE_TOKEN (value));
 }
 
+static gsize
+vivi_code_compiler_action_get_size (ViviCodeCompilerAction *action)
+{
+  g_return_val_if_fail (action != NULL, 0);
+
+  if (action->id & 0x80) {
+    return 3 +
+      (action->data != NULL ? swfdec_bots_get_bytes (action->data) : 0);
+  } else {
+    g_assert (action->data == NULL ||
+	swfdec_bots_get_bytes (action->data) == 0);
+    return 1;
+  }
+}
+
+static void
+vivi_code_compiler_action_write_data (ViviCodeCompilerAction *action,
+    SwfdecBots *data)
+{
+  g_return_if_fail (action != NULL);
+  g_return_if_fail (data != NULL);
+
+  swfdec_bots_put_u8 (data, action->id);
+  if (action->id & 0x80) {
+    if (action->data == NULL) {
+      swfdec_bots_put_u16 (data, 0);
+    } else {
+      swfdec_bots_put_u16 (data, swfdec_bots_get_bytes (action->data));
+      swfdec_bots_put_bots (data, action->data);
+    }
+  } else {
+    g_assert (action->data == NULL ||
+	swfdec_bots_get_bytes (action->data) == 0);
+  }
+}
+
+SwfdecBuffer *
+vivi_code_compiler_get_data (ViviCodeCompiler *compiler)
+{
+  SwfdecBots *data;
+  GSList *iter;
+
+  g_return_val_if_fail (VIVI_IS_CODE_COMPILER (compiler), NULL);
+  g_return_val_if_fail (compiler->current == NULL, NULL);
+
+  data = swfdec_bots_open ();
+  compiler->actions = g_slist_reverse (compiler->actions);
+  for (iter = compiler->actions; iter != NULL; iter = iter->next) {
+    vivi_code_compiler_action_write_data (iter->data, data);
+  }
+  compiler->actions = g_slist_reverse (compiler->actions);
+  return swfdec_bots_close (data);
+}
+
+gsize
+vivi_code_compiler_tail_size (ViviCodeCompiler *compiler)
+{
+  GSList *iter;
+  gsize size;
+
+  g_return_val_if_fail (VIVI_IS_CODE_COMPILER (compiler), 0);
+
+  size = 0;
+  for (iter = compiler->actions; iter != compiler->current; iter = iter->next)
+  {
+    size += vivi_code_compiler_action_get_size (iter->data);
+  }
+  return size;
+}
 
 void
-vivi_code_compiler_add_action (ViviCodeCompiler *compiler,
+vivi_code_compiler_begin_action (ViviCodeCompiler *compiler,
     SwfdecAsAction action)
 {
   g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
 
-  if (compiler->action != NULL)
-    compiler->actions = g_slist_prepend (compiler->actions, compiler->action);
-
   compiler->action = g_new0 (ViviCodeCompilerAction, 1);
   compiler->action->id = action;
   compiler->action->data = swfdec_bots_open ();
+  compiler->action->parent = compiler->current;
+
+  compiler->actions = g_slist_prepend (compiler->actions, compiler->action);
+  compiler->current = compiler->actions;
 }
 
 void
 vivi_code_compiler_end_action (ViviCodeCompiler *compiler)
 {
-  SwfdecBuffer *buffer;
-
   g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
-  g_return_if_fail (compiler->action != NULL);
-
-  buffer = swfdec_bots_close (compiler->action->data);
+  g_return_if_fail (compiler->current != NULL);
 
-  g_assert (compiler->action->id & 0x80 || buffer->length == 0);
-
-  swfdec_bots_put_u8 (compiler->data, compiler->action->id);
-  if (compiler->action->id & 0x80) {
-    swfdec_bots_put_u16 (compiler->data, buffer->length);
-    swfdec_bots_put_buffer (compiler->data, buffer);
-  }
-  swfdec_buffer_unref (buffer);
-
-  g_free (compiler->action);
-
-  if (compiler->actions != NULL) {
-    compiler->action = compiler->actions->data;
-    compiler->actions =
-      g_slist_delete_link (compiler->actions, compiler->actions);
+  compiler->current = compiler->action->parent;
+  if (compiler->current != NULL) {
+    compiler->action = compiler->current->data;
   } else {
     compiler->action = NULL;
   }
 }
 
+void
+vivi_code_compiler_write_empty_action (ViviCodeCompiler *compiler,
+    SwfdecAsAction id)
+{
+  ViviCodeCompilerAction *action;
+
+  action = g_new0 (ViviCodeCompilerAction, 1);
+  action->id = id;
+  action->data = NULL;
+  action->parent = NULL;
+
+  compiler->actions = g_slist_prepend (compiler->actions, action);
+}
+
 void vivi_code_compiler_write_u8 (ViviCodeCompiler *compiler, guint value)
 {
   g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
@@ -157,10 +212,29 @@ void vivi_code_compiler_write_u8 (ViviCodeCompiler *compiler, guint value)
   swfdec_bots_put_u8 (compiler->action->data, value);
 }
 
+void vivi_code_compiler_write_u16 (ViviCodeCompiler *compiler, guint value)
+{
+  g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
+  g_return_if_fail (compiler->action != NULL);
+
+  swfdec_bots_put_u16 (compiler->action->data, value);
+}
+
+void vivi_code_compiler_write_s16 (ViviCodeCompiler *compiler, guint value)
+{
+  g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
+  g_return_if_fail (compiler->action != NULL);
+
+  swfdec_bots_put_s16 (compiler->action->data, value);
+}
+
 void
 vivi_code_compiler_write_double (ViviCodeCompiler *compiler, double value)
 {
-  // TODO
+  g_return_if_fail (VIVI_IS_CODE_COMPILER (compiler));
+  g_return_if_fail (compiler->action != NULL);
+
+  swfdec_bots_put_double (compiler->action->data, value);
 }
 
 void
diff --git a/vivified/code/vivi_code_compiler.h b/vivified/code/vivi_code_compiler.h
index 34bc5e4..afaddad 100644
--- a/vivified/code/vivi_code_compiler.h
+++ b/vivified/code/vivi_code_compiler.h
@@ -40,18 +40,18 @@ typedef struct _ViviCodeCompilerClass ViviCodeCompilerClass;
 #define VIVI_CODE_COMPILER_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_COMPILER, ViviCodeCompilerClass))
 
 typedef struct {
-  SwfdecAsAction	id;
-  SwfdecBots		*data;
+  SwfdecAsAction		id;
+  SwfdecBots *			data;
+  GSList *			parent;
 } ViviCodeCompilerAction;
 
 struct _ViviCodeCompiler
 {
   GObject			object;
 
-  SwfdecBots			*data;
-
-  ViviCodeCompilerAction	*action;
-  GSList			*actions;	// ViviCodeCompilerAction
+  GSList *			actions;
+  GSList *			current;
+  ViviCodeCompilerAction *	action;
 };
 
 struct _ViviCodeCompilerClass
@@ -70,11 +70,17 @@ void		vivi_code_compiler_compile_token	(ViviCodeCompiler *	compiler,
 void		vivi_code_compiler_compile_value	(ViviCodeCompiler *	compiler,
 							 ViviCodeValue *	value);
 
-void		vivi_code_compiler_add_action		(ViviCodeCompiler *	compiler,
+gsize		vivi_code_compiler_tail_size		(ViviCodeCompiler *	compiler);
+
+void		vivi_code_compiler_begin_action		(ViviCodeCompiler *	compiler,
 							 SwfdecAsAction		action);
 void		vivi_code_compiler_end_action		(ViviCodeCompiler *	compiler);
+void		vivi_code_compiler_write_empty_action	(ViviCodeCompiler *	compiler,
+							 SwfdecAsAction		action);
 
 void		vivi_code_compiler_write_u8		(ViviCodeCompiler *	compiler, guint value);
+void		vivi_code_compiler_write_u16		(ViviCodeCompiler *	compiler, guint value);
+void		vivi_code_compiler_write_s16		(ViviCodeCompiler *	compiler, guint value);
 void		vivi_code_compiler_write_double		(ViviCodeCompiler *	compiler, double value);
 void		vivi_code_compiler_write_string		(ViviCodeCompiler *	compiler, const char *value);
 
commit 9c49486b107447736904ccc8282acf972ff3b34e
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Tue Apr 8 21:35:31 2008 +0300

    Add few swfdec_bots methods

diff --git a/swfdec/swfdec_bots.c b/swfdec/swfdec_bots.c
index 680108e..cc5eb2c 100644
--- a/swfdec/swfdec_bots.c
+++ b/swfdec/swfdec_bots.c
@@ -64,7 +64,7 @@ swfdec_bots_close (SwfdecBots *bots)
   return buffer;
 }
 
-unsigned int
+gsize
 swfdec_bots_get_bits (SwfdecBots *bots)
 {
   g_return_val_if_fail (bots != NULL, 0);
@@ -72,7 +72,17 @@ swfdec_bots_get_bits (SwfdecBots *bots)
   return (bots->ptr - bots->data) * 8 + bots->idx;
 }
 
-unsigned int
+gsize
+swfdec_bots_get_bytes (SwfdecBots *bots)
+{
+  g_return_val_if_fail (bots != NULL, 0);
+
+  g_assert (bots->idx == 0);
+
+  return swfdec_bots_get_bits (bots) / 8;
+}
+
+gsize
 swfdec_bots_left (SwfdecBots *bots)
 {
   g_return_val_if_fail (bots != NULL, 0);
@@ -130,6 +140,20 @@ swfdec_bots_put_buffer (SwfdecBots *bots, SwfdecBuffer *buffer)
 }
 
 void
+swfdec_bots_put_bots (SwfdecBots *bots, SwfdecBots *other)
+{
+  gsize bytes;
+
+  g_return_if_fail (bots != NULL);
+  g_return_if_fail (other != NULL);
+
+  bytes = swfdec_bots_get_bytes (other);
+  swfdec_bots_prepare_bytes (bots, bytes);
+  memcpy (bots->ptr, other->data, bytes);
+  bots->ptr += bytes;
+}
+
+void
 swfdec_bots_put_u8 (SwfdecBots *bots, guint i)
 {
   g_return_if_fail (i <= G_MAXUINT8);
@@ -150,6 +174,16 @@ swfdec_bots_put_u16 (SwfdecBots *bots, guint i)
 }
 
 void
+swfdec_bots_put_s16 (SwfdecBots *bots, int i)
+{
+  g_return_if_fail (i >= G_MININT16 && i <= G_MAXINT16);
+
+  swfdec_bots_prepare_bytes (bots, 2);
+  *(guint16 *)bots->ptr = GINT16_TO_LE (i);
+  bots->ptr += 2;
+}
+
+void
 swfdec_bots_put_u32 (SwfdecBots *bots, guint i)
 {
   g_return_if_fail (i <= G_MAXUINT32);
@@ -217,6 +251,29 @@ swfdec_bots_put_string (SwfdecBots *bots, const char *s)
   bots->ptr += len;
 }
 
+ /* If little endian x86 byte order is 0 1 2 3 4 5 6 7 and PPC32 byte order is
+ * 7 6 5 4 3 2 1 0, then Flash uses 4 5 6 7 0 1 2 3. */
+void
+swfdec_bots_put_double (SwfdecBots *bots, double value)
+{
+  union {
+    guint32 i[2];
+    double d;
+  } conv;
+
+  swfdec_bots_ensure_bits (bots, 8);
+
+  conv.d = value;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+  swfdec_bots_put_u32 (bots, conv.i[1]);
+  swfdec_bots_put_u32 (bots, conv.i[0]);
+#else
+  swfdec_bots_put_u32 (bots, GUINT32_TO_LE (conv.i[0]));
+  swfdec_bots_put_u32 (bots, GUINT32_TO_LE (conv.i[1]));
+#endif
+}
+
 static guint
 swfdec_bots_bits_required (guint x)
 {
diff --git a/swfdec/swfdec_bots.h b/swfdec/swfdec_bots.h
index 17da233..4af6f19 100644
--- a/swfdec/swfdec_bots.h
+++ b/swfdec/swfdec_bots.h
@@ -42,8 +42,9 @@ struct _SwfdecBots {
 SwfdecBots *	swfdec_bots_open			(void);
 SwfdecBuffer *	swfdec_bots_close		(SwfdecBots *		bots);
 
-unsigned int	swfdec_bots_get_bits		(SwfdecBots *		bots);
-unsigned int	swfdec_bots_left	  		(SwfdecBots *		bots);
+gsize		swfdec_bots_get_bits		(SwfdecBots *		bots);
+gsize		swfdec_bots_get_bytes		(SwfdecBots *		bots);
+gsize		swfdec_bots_left		(SwfdecBots *		bots);
 void		swfdec_bots_ensure_bits		(SwfdecBots *		bots,
 						 unsigned int		bits);
 void		swfdec_bots_prepare_bytes	(SwfdecBots *		bots,
@@ -62,14 +63,20 @@ void		swfdec_bots_put_data		(SwfdecBots *		bots,
 						 guint			length);
 void		swfdec_bots_put_buffer		(SwfdecBots *		bots,
 						 SwfdecBuffer *		buffer);
+void		swfdec_bots_put_bots		(SwfdecBots *		bots,
+						 SwfdecBots *		other);
 void		swfdec_bots_put_u8		(SwfdecBots *		bots,
 						 guint	  		i);
 void		swfdec_bots_put_u16		(SwfdecBots *		bots,
 						 guint			i);
+void		swfdec_bots_put_s16		(SwfdecBots *		bots,
+						 gint			i);
 void		swfdec_bots_put_u32		(SwfdecBots *		bots,
 						 guint			i);
 void		swfdec_bots_put_string		(SwfdecBots *		bots,
 						 const char *		s);
+void		swfdec_bots_put_double		(SwfdecBots *		bots,
+						 double			value);
 
 void		swfdec_bots_put_rgb		(SwfdecBots *		bots,
 						 SwfdecColor		color);
commit 0cfa409ff0dec8776fd9c16291c1f68fb478a5f0
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sun Apr 6 17:37:59 2008 +0300

    Make the parser handle automatic semicolon insertion

diff --git a/vivified/code/vivi_compiler.c b/vivified/code/vivi_compiler.c
index f09f6ab..e9696b0 100644
--- a/vivified/code/vivi_compiler.c
+++ b/vivified/code/vivi_compiler.c
@@ -168,6 +168,33 @@ check_token (ParseData *data, ViviCompilerScannerToken token)
   return TRUE;
 }
 
+static gboolean
+check_automatic_semicolon (ParseData *data)
+{
+  if (check_token (data, TOKEN_SEMICOLON))
+    return TRUE;
+  if (check_line_terminator (data))
+    return TRUE;
+
+  vivi_compiler_scanner_peek_next_token (data->scanner);
+  if (data->scanner->next_token == TOKEN_BRACE_LEFT ||
+      data->scanner->next_token == TOKEN_EOF)
+    return TRUE;
+
+  return FALSE;
+}
+
+static gboolean
+check_restricted_semicolon (ParseData *data)
+{
+  if (check_token (data, TOKEN_SEMICOLON))
+    return TRUE;
+  if (check_line_terminator (data))
+    return TRUE;
+
+  return FALSE;
+}
+
 static void
 free_value_list (ViviCodeValue **list)
 {
@@ -939,15 +966,8 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
   if (status != STATUS_OK)
     return status;
 
-  if (check_line_terminator (data)) {
-    g_object_unref (*value);
-    *value = NULL;
-    if (*statement != NULL) {
-      g_object_unref (*statement);
-      *statement = NULL;
-    }
-    return FAIL_LINE_TERMINATOR_OR (TOKEN_INCREASE, TOKEN_DESCREASE);
-  }
+  if (check_line_terminator (data))
+    return status;
 
   if (check_token (data, TOKEN_INCREASE)) {
     operator = "+";
@@ -1414,11 +1434,11 @@ parse_trace_statement (ParseData *data, ViviCodeStatement **statement)
     return FAIL (TOKEN_PARENTHESIS_RIGHT);
   }
 
-  if (!check_token (data, TOKEN_SEMICOLON)) {
+  if (!check_automatic_semicolon (data)) {
     g_object_unref (value);
     if (expression_statement != NULL)
       g_object_unref (expression_statement);
-    return FAIL (TOKEN_PARENTHESIS_RIGHT);
+    return FAIL (TOKEN_SEMICOLON);
   }
 
   *statement = vivi_code_trace_new (value);
@@ -1439,10 +1459,7 @@ parse_continue_or_break_statement (ParseData *data,
   if (!check_token (data, token))
     return CANCEL (token);
 
-  if (check_line_terminator (data))
-    return FAIL_LINE_TERMINATOR_OR (TOKEN_SEMICOLON, ERROR_TOKEN_IDENTIFIER);
-
-  if (!check_token (data, TOKEN_SEMICOLON)) {
+  if (!check_restricted_semicolon (data)) {
     ParseStatus status;
     ViviCodeValue *identifier;
 
@@ -1454,7 +1471,7 @@ parse_continue_or_break_statement (ParseData *data,
 
     vivi_compiler_add_goto (data, VIVI_COMPILER_GOTO_NAME (*statement));
 
-    if (!check_token (data, TOKEN_SEMICOLON)) {
+    if (!check_automatic_semicolon (data)) {
       g_object_unref (*statement);
       *statement = NULL;
       return FAIL (TOKEN_SEMICOLON);
@@ -1503,7 +1520,7 @@ parse_throw_statement (ParseData *data, ViviCodeStatement **statement)
   *statement =
     vivi_compiler_join_statements (expression_statement, *statement);
 
-  if (!check_token (data, TOKEN_SEMICOLON)) {
+  if (!check_automatic_semicolon (data)) {
     g_object_unref (*statement);
     *statement = NULL;
     return FAIL (TOKEN_SEMICOLON);
@@ -1520,12 +1537,9 @@ parse_return_statement (ParseData *data, ViviCodeStatement **statement)
   if (!check_token (data, TOKEN_RETURN))
     return CANCEL (TOKEN_RETURN);
 
-  if (check_line_terminator (data))
-    return FAIL_LINE_TERMINATOR_OR (TOKEN_SEMICOLON, TOKEN_IDENTIFIER);
-
   *statement = vivi_code_return_new ();
 
-  if (!check_token (data, TOKEN_SEMICOLON)) {
+  if (!check_restricted_semicolon (data)) {
     ParseStatus status;
     ViviCodeValue *value;
     ViviCodeStatement *expression_statement;
@@ -1543,7 +1557,7 @@ parse_return_statement (ParseData *data, ViviCodeStatement **statement)
     *statement =
       vivi_compiler_join_statements (expression_statement, *statement);
 
-    if (!check_token (data, TOKEN_SEMICOLON)) {
+    if (!check_automatic_semicolon (data)) {
       g_object_unref (*statement);
       *statement = NULL;
       return FAIL (TOKEN_SEMICOLON);
@@ -1594,7 +1608,7 @@ parse_iteration_statement (ParseData *data, ViviCodeStatement **statement)
       return FAIL (TOKEN_PARENTHESIS_LEFT);
     }
 
-    if (!check_token (data, TOKEN_SEMICOLON)) {
+    if (!check_automatic_semicolon (data)) {
       g_object_unref (loop_statement);
       g_object_unref (condition);
       if (condition_statement != NULL)
@@ -1868,7 +1882,7 @@ parse_expression_statement (ParseData *data, ViviCodeStatement **statement)
     }
   }
 
-  if (!check_token (data, TOKEN_SEMICOLON)) {
+  if (!check_automatic_semicolon (data)) {
     g_object_unref (value);
     if (*statement != NULL) {
       g_object_unref (*statement);
@@ -1961,7 +1975,7 @@ parse_variable_statement (ParseData *data, ViviCodeStatement **statement)
   if (status != STATUS_OK)
     return FAIL_CHILD (status);
 
-  if (!check_token (data, TOKEN_SEMICOLON)) {
+  if (!check_automatic_semicolon (data)) {
     g_object_unref (*statement);
     *statement = NULL;
     return FAIL (TOKEN_SEMICOLON);


More information about the Swfdec-commits mailing list