[Swfdec-commits] 2 commits - vivified/code

Benjamin Otte company at kemper.freedesktop.org
Wed Mar 26 08:56:35 PDT 2008


 vivified/code/Makefile.am               |    2 
 vivified/code/vivi_code_function_call.c |   10 ++
 vivified/code/vivi_code_function_call.h |    9 +-
 vivified/code/vivi_code_init_object.c   |  131 ++++++++++++++++++++++++++++++++
 vivified/code/vivi_code_init_object.h   |   59 ++++++++++++++
 vivified/code/vivi_decompiler.c         |   76 ++++++++++++------
 6 files changed, 260 insertions(+), 27 deletions(-)

New commits:
commit 2dea98bad5526a00e361a5545df669e46db88546
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Mar 26 16:56:29 2008 +0100

    implement NewObject/NewMethod bytecodes

diff --git a/vivified/code/vivi_code_function_call.c b/vivified/code/vivi_code_function_call.c
index a16a9e2..3964f5a 100644
--- a/vivified/code/vivi_code_function_call.c
+++ b/vivified/code/vivi_code_function_call.c
@@ -79,6 +79,8 @@ vivi_code_function_call_print (ViviCodeToken *token, ViviCodePrinter*printer)
   char *varname;
   guint i;
 
+  if (call->construct)
+    vivi_code_printer_print (printer, "new ");
   if (call->name) {
     if (VIVI_IS_CODE_CONSTANT (call->name))
       varname = vivi_code_constant_get_variable_name (VIVI_CODE_CONSTANT (call->name));
@@ -167,6 +169,14 @@ vivi_code_function_call_new (ViviCodeValue *value, ViviCodeValue *name)
 }
 
 void
+vivi_code_function_call_set_construct (ViviCodeFunctionCall *call, gboolean construct)
+{
+  g_return_if_fail (VIVI_IS_CODE_FUNCTION_CALL (call));
+
+  call->construct = construct;
+}
+
+void
 vivi_code_function_call_add_argument (ViviCodeFunctionCall *call, ViviCodeValue *argument)
 {
   g_return_if_fail (VIVI_IS_CODE_FUNCTION_CALL (call));
diff --git a/vivified/code/vivi_code_function_call.h b/vivified/code/vivi_code_function_call.h
index cd3ce32..4b3ddcf 100644
--- a/vivified/code/vivi_code_function_call.h
+++ b/vivified/code/vivi_code_function_call.h
@@ -39,9 +39,10 @@ struct _ViviCodeFunctionCall
 {
   ViviCodeValue		parent;
 
-  ViviCodeValue *	value;
-  ViviCodeValue *	name;
-  GPtrArray *		arguments;
+  gboolean		construct;	/* This is a constructor call */
+  ViviCodeValue *	value;		/* value to call function with */
+  ViviCodeValue *	name;		/* property to get */
+  GPtrArray *		arguments;	/* array of ViviCodeValue containing the function's arguments */
 };
 
 struct _ViviCodeFunctionCallClass
@@ -54,6 +55,8 @@ GType			vivi_code_function_call_get_type   	(void);
 ViviCodeValue *		vivi_code_function_call_new		(ViviCodeValue *	value,
 								 ViviCodeValue *	name);
 
+void			vivi_code_function_call_set_construct	(ViviCodeFunctionCall * call,
+								 gboolean		construct);
 void			vivi_code_function_call_add_argument	(ViviCodeFunctionCall *	call,
 								 ViviCodeValue *	argument);
 
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index 368ccfb..78a8bb3 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -404,7 +404,7 @@ vivi_decompile_duplicate (ViviDecompilerBlock *block, ViviDecompilerState *state
   return TRUE;
 }
 
-static gboolean
+static ViviCodeValue *
 vivi_decompile_function_call (ViviDecompilerBlock *block, ViviDecompilerState *state,
     ViviCodeValue *value, ViviCodeValue *name, ViviCodeValue *args)
 {
@@ -424,7 +424,7 @@ vivi_decompile_function_call (ViviDecompilerBlock *block, ViviDecompilerState *s
     vivi_decompiler_block_add_error (block, state, "could not determine function argument count");
     g_object_unref (args);
     g_object_unref (call);
-    return FALSE;
+    return NULL;
   }
   g_object_unref (args);
 
@@ -435,32 +435,28 @@ vivi_decompile_function_call (ViviDecompilerBlock *block, ViviDecompilerState *s
     g_object_unref (value);
   }
   vivi_decompiler_state_push (state, call);
-  return TRUE;
-}
-
-static gboolean
-vivi_decompile_call_function (ViviDecompilerBlock *block, ViviDecompilerState *state,
-    guint code, const guint8 *data, guint len)
-{
-  ViviCodeValue *name, *args;
-
-  name = vivi_decompiler_state_pop (state);
-  args = vivi_decompiler_state_pop (state);
-
-  return vivi_decompile_function_call (block, state, NULL, name, args);
+  return call;
 }
 
 static gboolean
-vivi_decompile_call_method (ViviDecompilerBlock *block, ViviDecompilerState *state,
+vivi_decompile_call (ViviDecompilerBlock *block, ViviDecompilerState *state,
     guint code, const guint8 *data, guint len)
 {
-  ViviCodeValue *value, *name, *args;
+  ViviCodeValue *call, *name, *value, *args;
 
   name = vivi_decompiler_state_pop (state);
-  value = vivi_decompiler_state_pop (state);
+  if (code == SWFDEC_AS_ACTION_CALL_METHOD || code == SWFDEC_AS_ACTION_NEW_METHOD)
+    value = vivi_decompiler_state_pop (state);
+  else
+    value = NULL;
   args = vivi_decompiler_state_pop (state);
 
-  return vivi_decompile_function_call (block, state, value, name, args);
+  call = vivi_decompile_function_call (block, state, value, name, args);
+  if (!call)
+    return FALSE;
+  if (code == SWFDEC_AS_ACTION_NEW_OBJECT || code == SWFDEC_AS_ACTION_NEW_METHOD)
+    vivi_code_function_call_set_construct (VIVI_CODE_FUNCTION_CALL (call), TRUE);
+  return TRUE;
 }
 
 static gboolean
@@ -686,10 +682,10 @@ static DecompileFunc decompile_funcs[256] = {
   [SWFDEC_AS_ACTION_DELETE] = NULL,
   [SWFDEC_AS_ACTION_DELETE2] = NULL,
   [SWFDEC_AS_ACTION_DEFINE_LOCAL] = NULL,
-  [SWFDEC_AS_ACTION_CALL_FUNCTION] = vivi_decompile_call_function,
+  [SWFDEC_AS_ACTION_CALL_FUNCTION] = vivi_decompile_call,
   [SWFDEC_AS_ACTION_RETURN] = vivi_decompile_return,
   [SWFDEC_AS_ACTION_MODULO] = NULL,
-  [SWFDEC_AS_ACTION_NEW_OBJECT] = NULL,
+  [SWFDEC_AS_ACTION_NEW_OBJECT] = vivi_decompile_call,
   [SWFDEC_AS_ACTION_DEFINE_LOCAL2] = NULL,
   [SWFDEC_AS_ACTION_INIT_ARRAY] = NULL,
   [SWFDEC_AS_ACTION_INIT_OBJECT] = vivi_decompile_init_object,
@@ -707,8 +703,8 @@ static DecompileFunc decompile_funcs[256] = {
   [SWFDEC_AS_ACTION_SET_MEMBER] = vivi_decompile_set_member,
   [SWFDEC_AS_ACTION_INCREMENT] = NULL,
   [SWFDEC_AS_ACTION_DECREMENT] = NULL,
-  [SWFDEC_AS_ACTION_CALL_METHOD] = vivi_decompile_call_method,
-  [SWFDEC_AS_ACTION_NEW_METHOD] = NULL,
+  [SWFDEC_AS_ACTION_CALL_METHOD] = vivi_decompile_call,
+  [SWFDEC_AS_ACTION_NEW_METHOD] = vivi_decompile_call,
   [SWFDEC_AS_ACTION_INSTANCE_OF] = NULL,
   [SWFDEC_AS_ACTION_ENUMERATE2] = NULL,
   [SWFDEC_AS_ACTION_BREAKPOINT] = NULL,
commit fcf57ad9ecd2548af7ad632e1fc2b418be459f08
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Mar 26 16:08:17 2008 +0100

    add init object support
    
    init objects look like this:
    foo = { bla: 42 };

diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 1148938..786c688 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -19,6 +19,7 @@ libvivified_compiler_la_SOURCES = \
 	vivi_code_get_url.c \
 	vivi_code_goto.c \
 	vivi_code_if.c \
+	vivi_code_init_object.c \
 	vivi_code_label.c \
 	vivi_code_loop.c \
 	vivi_code_printer.c \
@@ -50,6 +51,7 @@ noinst_HEADERS = \
 	vivi_code_get_url.h \
 	vivi_code_goto.h \
 	vivi_code_if.h \
+	vivi_code_init_object.h \
 	vivi_code_label.h \
 	vivi_code_loop.h \
 	vivi_code_printer.h \
diff --git a/vivified/code/vivi_code_init_object.c b/vivified/code/vivi_code_init_object.c
new file mode 100644
index 0000000..4582b44
--- /dev/null
+++ b/vivified/code/vivi_code_init_object.c
@@ -0,0 +1,131 @@
+/* Vivified
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_init_object.h"
+#include "vivi_code_printer.h"
+
+G_DEFINE_TYPE (ViviCodeInitObject, vivi_code_init_object, VIVI_TYPE_CODE_VALUE)
+
+typedef struct _VariableEntry VariableEntry;
+struct _VariableEntry {
+  ViviCodeValue *	name;
+  ViviCodeValue *	value;
+};
+
+static void
+vivi_code_init_object_dispose (GObject *object)
+{
+  ViviCodeInitObject *obj = VIVI_CODE_INIT_OBJECT (object);
+  guint i;
+
+  for (i = 0; i < obj->variables->len; i++) {
+    VariableEntry *entry = &g_array_index (obj->variables, VariableEntry, i);
+    g_object_unref (entry->name);
+    g_object_unref (entry->value);
+  }
+  g_array_free (obj->variables, TRUE);
+
+  G_OBJECT_CLASS (vivi_code_init_object_parent_class)->dispose (object);
+}
+
+static ViviCodeValue * 
+vivi_code_init_object_optimize (ViviCodeValue *value, SwfdecAsValueType hint)
+{
+  /* FIXME: write */
+
+  return g_object_ref (value);
+}
+
+static void
+vivi_code_init_object_print (ViviCodeToken *token, ViviCodePrinter*printer)
+{
+  ViviCodeInitObject *object = VIVI_CODE_INIT_OBJECT (token);
+  guint i;
+
+  vivi_code_printer_print (printer, "{");
+  for (i = 0; i < object->variables->len; i++) {
+    VariableEntry *entry = &g_array_index (object->variables, VariableEntry, i);
+    if (i > 0)
+      vivi_code_printer_print (printer, ", ");
+    /* FIXME: precedences? */
+    vivi_code_printer_print_value (printer, entry->name, VIVI_PRECEDENCE_COMMA);
+    vivi_code_printer_print (printer, ": ");
+    vivi_code_printer_print_value (printer, entry->value, VIVI_PRECEDENCE_COMMA);
+  }
+  vivi_code_printer_print (printer, "}");
+}
+
+static gboolean
+vivi_code_init_object_is_constant (ViviCodeValue *value)
+{
+  /* not constant, because we return a new object every time */
+  return FALSE;
+}
+
+static void
+vivi_code_init_object_class_init (ViviCodeInitObjectClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+  ViviCodeValueClass *value_class = VIVI_CODE_VALUE_CLASS (klass);
+
+  object_class->dispose = vivi_code_init_object_dispose;
+
+  token_class->print = vivi_code_init_object_print;
+
+  value_class->is_constant = vivi_code_init_object_is_constant;
+  value_class->optimize = vivi_code_init_object_optimize;
+}
+
+static void
+vivi_code_init_object_init (ViviCodeInitObject *object)
+{
+  ViviCodeValue *value = VIVI_CODE_VALUE (object);
+
+  object->variables = g_array_new (FALSE, FALSE, sizeof (VariableEntry));
+
+  vivi_code_value_set_precedence (value, VIVI_PRECEDENCE_PARENTHESIS);
+}
+
+ViviCodeValue *
+vivi_code_init_object_new (void)
+{
+  return g_object_new (VIVI_TYPE_CODE_INIT_OBJECT, NULL);
+}
+
+void
+vivi_code_init_object_add_variable (ViviCodeInitObject *object,
+    ViviCodeValue *name, ViviCodeValue *value)
+{
+  VariableEntry entry;
+
+  g_return_if_fail (VIVI_IS_CODE_INIT_OBJECT (object));
+  g_return_if_fail (VIVI_IS_CODE_VALUE (name));
+  g_return_if_fail (VIVI_IS_CODE_VALUE (value));
+
+  entry.name = g_object_ref (name);
+  entry.value = g_object_ref (value);
+
+  g_array_append_val (object->variables, entry);
+}
+
diff --git a/vivified/code/vivi_code_init_object.h b/vivified/code/vivi_code_init_object.h
new file mode 100644
index 0000000..96208c4
--- /dev/null
+++ b/vivified/code/vivi_code_init_object.h
@@ -0,0 +1,59 @@
+/* Vivified
+ * Copyright (C) 2008 Benjamin Otte <otte at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#ifndef _VIVI_CODE_INIT_OBJECT_H_
+#define _VIVI_CODE_INIT_OBJECT_H_
+
+#include <vivified/code/vivi_code_value.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeInitObject ViviCodeInitObject;
+typedef struct _ViviCodeInitObjectClass ViviCodeInitObjectClass;
+
+#define VIVI_TYPE_CODE_INIT_OBJECT                    (vivi_code_init_object_get_type())
+#define VIVI_IS_CODE_INIT_OBJECT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_INIT_OBJECT))
+#define VIVI_IS_CODE_INIT_OBJECT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_INIT_OBJECT))
+#define VIVI_CODE_INIT_OBJECT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_INIT_OBJECT, ViviCodeInitObject))
+#define VIVI_CODE_INIT_OBJECT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_INIT_OBJECT, ViviCodeInitObjectClass))
+#define VIVI_CODE_INIT_OBJECT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_INIT_OBJECT, ViviCodeInitObjectClass))
+
+struct _ViviCodeInitObject
+{
+  ViviCodeValue		value;
+
+  GArray *		variables;
+};
+
+struct _ViviCodeInitObjectClass
+{
+  ViviCodeValueClass	value_class;
+};
+
+GType			vivi_code_init_object_get_type   	(void);
+
+ViviCodeValue *		vivi_code_init_object_new		(void);
+
+void			vivi_code_init_object_add_variable	(ViviCodeInitObject *	object,
+								 ViviCodeValue *	name,
+								 ViviCodeValue *	value);
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index de7657f..368ccfb 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -40,6 +40,7 @@
 #include "vivi_code_get_url.h"
 #include "vivi_code_goto.h"
 #include "vivi_code_if.h"
+#include "vivi_code_init_object.h"
 #include "vivi_code_loop.h"
 #include "vivi_code_return.h"
 #include "vivi_code_trace.h"
@@ -606,6 +607,37 @@ vivi_decompile_store_register (ViviDecompilerBlock *block, ViviDecompilerState *
   return TRUE;
 }
 
+static gboolean
+vivi_decompile_init_object (ViviDecompilerBlock *block, ViviDecompilerState *state,
+    guint code, const guint8 *data, guint len)
+{
+  ViviCodeValue *args, *init, *name, *value;
+  double d;
+  guint i, count;
+
+  args = vivi_decompiler_state_pop (state);
+  if (!VIVI_IS_CODE_CONSTANT (args) || 
+      vivi_code_constant_get_value_type (VIVI_CODE_CONSTANT (args)) != SWFDEC_AS_TYPE_NUMBER ||
+      ((count = d = vivi_code_constant_get_number (VIVI_CODE_CONSTANT (args))) != d)) {
+    vivi_decompiler_block_add_error (block, state, "could not determine init object argument count");
+    g_object_unref (args);
+    return FALSE;
+  }
+  g_object_unref (args);
+  count = MIN (count, (vivi_decompiler_state_get_stack_depth (state) + 1) / 2);
+
+  init = vivi_code_init_object_new ();
+  for (i = 0; i < count; i++) {
+    value = vivi_decompiler_state_pop (state);
+    name = vivi_decompiler_state_pop (state);
+    vivi_code_init_object_add_variable (VIVI_CODE_INIT_OBJECT (init), name, value);
+    g_object_unref (name);
+    g_object_unref (value);
+  }
+  vivi_decompiler_state_push (state, init);
+  return TRUE;
+}
+
 static DecompileFunc decompile_funcs[256] = {
   [SWFDEC_AS_ACTION_END] = vivi_decompile_end,
   [SWFDEC_AS_ACTION_NEXT_FRAME] = NULL,
@@ -660,7 +692,7 @@ static DecompileFunc decompile_funcs[256] = {
   [SWFDEC_AS_ACTION_NEW_OBJECT] = NULL,
   [SWFDEC_AS_ACTION_DEFINE_LOCAL2] = NULL,
   [SWFDEC_AS_ACTION_INIT_ARRAY] = NULL,
-  [SWFDEC_AS_ACTION_INIT_OBJECT] = NULL,
+  [SWFDEC_AS_ACTION_INIT_OBJECT] = vivi_decompile_init_object,
   [SWFDEC_AS_ACTION_TYPE_OF] = NULL,
   [SWFDEC_AS_ACTION_TARGET_PATH] = NULL,
   [SWFDEC_AS_ACTION_ENUMERATE] = NULL,


More information about the Swfdec-commits mailing list