[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