[Swfdec-commits] vivified/code
Benjamin Otte
company at kemper.freedesktop.org
Sun Apr 13 13:17:35 PDT 2008
vivified/code/Makefile.am | 9 +
vivified/code/vivi_code_and.c | 59 ++++++++++++
vivified/code/vivi_code_and.h | 55 +++++++++++
vivified/code/vivi_code_binary.c | 97 +--------------------
vivified/code/vivi_code_binary.h | 13 +-
vivified/code/vivi_code_binary_default.c | 62 +++++++++++++
vivified/code/vivi_code_binary_default.h | 41 ++++++++
vivified/code/vivi_code_defaults.h | 52 +++++++++++
vivified/code/vivi_code_or.c | 59 ++++++++++++
vivified/code/vivi_code_or.h | 55 +++++++++++
vivified/code/vivi_code_value.h | 1
vivified/code/vivi_decompiler.c | 23 +++-
vivified/code/vivi_parser.c | 143 +++++++++++++++++++------------
13 files changed, 515 insertions(+), 154 deletions(-)
New commits:
commit 4964ab12312bfa961b02e240cde99ba041821283
Author: Benjamin Otte <otte at gnome.org>
Date: Sun Apr 13 21:52:53 2008 +0200
convert binary handling to use one class per token
I'm not sure yet if it's a good idea. It feels cleaner though.
diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 789bae3..205e734 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -16,8 +16,10 @@ libvivified_compiler_la_LIBADD = \
libvivified-parser-lex.la
libvivified_compiler_la_SOURCES = \
+ vivi_code_and.c \
vivi_code_assignment.c \
vivi_code_binary.c \
+ vivi_code_binary_default.c \
vivi_code_block.c \
vivi_code_break.c \
vivi_code_comment.c \
@@ -34,6 +36,7 @@ libvivified_compiler_la_SOURCES = \
vivi_code_init_object.c \
vivi_code_label.c \
vivi_code_loop.c \
+ vivi_code_or.c \
vivi_code_play.c \
vivi_code_printer.c \
vivi_code_return.c \
@@ -58,14 +61,17 @@ libvivified_compiler_la_SOURCES = \
vivi_parser_scanner.c
noinst_HEADERS = \
+ vivi_code_and.h \
vivi_code_assignment.h \
- vivi_code_binary.c \
+ vivi_code_binary.h \
+ vivi_code_binary_default.h \
vivi_code_block.h \
vivi_code_break.h \
vivi_code_comment.h \
vivi_code_compiler.h \
vivi_code_constant.h \
vivi_code_continue.h \
+ vivi_code_defaults.h \
vivi_code_function.h \
vivi_code_function_call.h \
vivi_code_get.h \
@@ -76,6 +82,7 @@ noinst_HEADERS = \
vivi_code_init_object.h \
vivi_code_label.h \
vivi_code_loop.h \
+ vivi_code_or.h \
vivi_code_play.h \
vivi_code_printer.h \
vivi_code_return.h \
diff --git a/vivified/code/vivi_code_and.c b/vivified/code/vivi_code_and.c
new file mode 100644
index 0000000..b2af31c
--- /dev/null
+++ b/vivified/code/vivi_code_and.c
@@ -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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_and.h"
+
+G_DEFINE_TYPE (ViviCodeAnd, vivi_code_and, VIVI_TYPE_CODE_BINARY)
+
+static void
+vivi_code_and_class_init (ViviCodeAndClass *klass)
+{
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+ ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass);
+
+ token_class->compile = NULL; /* FIXME */
+
+ binary_class->operator_name = "&&";
+}
+
+static void
+vivi_code_and_init (ViviCodeAnd *and)
+{
+ vivi_code_value_set_precedence (VIVI_CODE_VALUE (and), VIVI_PRECEDENCE_AND);
+}
+
+ViviCodeValue *
+vivi_code_and_new (ViviCodeValue *left, ViviCodeValue *right)
+{
+ ViviCodeBinary *binary;
+
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
+
+ binary = g_object_new (VIVI_TYPE_CODE_AND, NULL);
+ binary->left = g_object_ref (left);
+ binary->right = g_object_ref (right);
+
+ return VIVI_CODE_VALUE (binary);
+}
+
diff --git a/vivified/code/vivi_code_and.h b/vivified/code/vivi_code_and.h
new file mode 100644
index 0000000..fbe3fa8
--- /dev/null
+++ b/vivified/code/vivi_code_and.h
@@ -0,0 +1,55 @@
+/* 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_AND_H_
+#define _VIVI_CODE_AND_H_
+
+#include <vivified/code/vivi_code_binary.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeAnd ViviCodeAnd;
+typedef struct _ViviCodeAndClass ViviCodeAndClass;
+
+#define VIVI_TYPE_CODE_AND (vivi_code_and_get_type())
+#define VIVI_IS_CODE_AND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_AND))
+#define VIVI_IS_CODE_AND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_AND))
+#define VIVI_CODE_AND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_AND, ViviCodeAnd))
+#define VIVI_CODE_AND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_AND, ViviCodeAndClass))
+#define VIVI_CODE_AND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_AND, ViviCodeAndClass))
+
+struct _ViviCodeAnd
+{
+ ViviCodeBinary binary;
+};
+
+struct _ViviCodeAndClass
+{
+ ViviCodeBinaryClass binary_class;
+};
+
+GType vivi_code_and_get_type (void);
+
+ViviCodeValue * vivi_code_and_new (ViviCodeValue * left,
+ ViviCodeValue * right);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_binary.c b/vivified/code/vivi_code_binary.c
index ec78597..2995c0e 100644
--- a/vivified/code/vivi_code_binary.c
+++ b/vivified/code/vivi_code_binary.c
@@ -27,37 +27,6 @@
#include "vivi_code_printer.h"
#include "vivi_code_compiler.h"
-static struct {
- const char * operation;
- guint bytecode;
- ViviPrecedence precedence;
-} operation_table[] = {
- { "add", SWFDEC_AS_ACTION_ADD, VIVI_PRECEDENCE_ADD },
- { "-", SWFDEC_AS_ACTION_SUBTRACT, VIVI_PRECEDENCE_ADD },
- { "*", SWFDEC_AS_ACTION_MULTIPLY, VIVI_PRECEDENCE_MULTIPLY },
- { "/", SWFDEC_AS_ACTION_DIVIDE, VIVI_PRECEDENCE_MULTIPLY },
- { "==", SWFDEC_AS_ACTION_EQUALS, VIVI_PRECEDENCE_EQUALITY },
- { "<", SWFDEC_AS_ACTION_LESS, VIVI_PRECEDENCE_RELATIONAL },
- { "and", SWFDEC_AS_ACTION_AND, VIVI_PRECEDENCE_AND },
- { "or", SWFDEC_AS_ACTION_OR, VIVI_PRECEDENCE_OR },
- { "eq", SWFDEC_AS_ACTION_STRING_EQUALS, VIVI_PRECEDENCE_EQUALITY },
- { "lt", SWFDEC_AS_ACTION_STRING_LESS, VIVI_PRECEDENCE_RELATIONAL },
- { "+", SWFDEC_AS_ACTION_ADD2, VIVI_PRECEDENCE_ADD },
- { "<", SWFDEC_AS_ACTION_LESS2, VIVI_PRECEDENCE_RELATIONAL },
- { "==", SWFDEC_AS_ACTION_EQUALS2, VIVI_PRECEDENCE_EQUALITY },
- { "&", SWFDEC_AS_ACTION_BIT_AND, VIVI_PRECEDENCE_BINARY_AND },
- { "|", SWFDEC_AS_ACTION_BIT_OR, VIVI_PRECEDENCE_BINARY_OR },
- { "^", SWFDEC_AS_ACTION_BIT_XOR, VIVI_PRECEDENCE_BINARY_XOR },
- { "<<", SWFDEC_AS_ACTION_BIT_LSHIFT, VIVI_PRECEDENCE_SHIFT },
- { ">>", SWFDEC_AS_ACTION_BIT_RSHIFT, VIVI_PRECEDENCE_SHIFT },
- { ">>>", SWFDEC_AS_ACTION_BIT_URSHIFT, VIVI_PRECEDENCE_SHIFT },
- { "===", SWFDEC_AS_ACTION_STRICT_EQUALS, VIVI_PRECEDENCE_EQUALITY },
- { ">", SWFDEC_AS_ACTION_GREATER, VIVI_PRECEDENCE_RELATIONAL },
- { "gt", SWFDEC_AS_ACTION_STRING_GREATER,VIVI_PRECEDENCE_RELATIONAL },
- { "&&", 0, VIVI_PRECEDENCE_AND },
- { "||", 0, VIVI_PRECEDENCE_OR }
-};
-
G_DEFINE_TYPE (ViviCodeBinary, vivi_code_binary, VIVI_TYPE_CODE_VALUE)
static void
@@ -75,28 +44,29 @@ static void
vivi_code_binary_print (ViviCodeToken *token, ViviCodePrinter*printer)
{
ViviCodeBinary *binary = VIVI_CODE_BINARY (token);
+ ViviCodeValue *value = VIVI_CODE_VALUE (token);
+ ViviCodeBinaryClass *klass = VIVI_CODE_BINARY_GET_CLASS (binary);
vivi_code_printer_print_value (printer, binary->left,
- operation_table[binary->operation_index].precedence);
+ vivi_code_value_get_precedence (value));
vivi_code_printer_print (printer, " ");
- vivi_code_printer_print (printer, operation_table[binary->operation_index].operation);
+ vivi_code_printer_print (printer, klass->operator_name);
vivi_code_printer_print (printer, " ");
vivi_code_printer_print_value (printer, binary->right,
- operation_table[binary->operation_index].precedence);
+ vivi_code_value_get_precedence (value));
}
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);
+ ViviCodeBinaryClass *klass = VIVI_CODE_BINARY_GET_CLASS (binary);
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);
+ g_assert (klass->bytecode != 0);
+ vivi_code_compiler_write_empty_action (compiler, klass->bytecode);
}
static gboolean
@@ -128,54 +98,3 @@ vivi_code_binary_init (ViviCodeBinary *binary)
{
}
-ViviCodeValue *
-vivi_code_binary_new_bytecode (ViviCodeValue *left, ViviCodeValue *right, guint code)
-{
- ViviCodeBinary *binary;
- guint id;
-
- g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
- g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
- for (id = 0; id < G_N_ELEMENTS (operation_table); id++) {
- if (operation_table[id].bytecode == code)
- break;
- }
- g_return_val_if_fail (id < G_N_ELEMENTS (operation_table), NULL);
-
- binary = g_object_new (VIVI_TYPE_CODE_BINARY, NULL);
- binary->left = g_object_ref (left);
- binary->right = g_object_ref (right);
- binary->operation_index = id;
-
- vivi_code_value_set_precedence (VIVI_CODE_VALUE (binary),
- operation_table[id].precedence);
-
- return VIVI_CODE_VALUE (binary);
-}
-
-ViviCodeValue *
-vivi_code_binary_new_name (ViviCodeValue *left, ViviCodeValue *right, const char *name)
-{
- ViviCodeBinary *binary;
- guint id;
-
- g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
- g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- for (id = 0; id < G_N_ELEMENTS (operation_table); id++) {
- if (g_str_equal (operation_table[id].operation, name))
- break;
- }
- g_return_val_if_fail (id < G_N_ELEMENTS (operation_table), NULL);
-
- binary = g_object_new (VIVI_TYPE_CODE_BINARY, NULL);
- binary->left = g_object_ref (left);
- binary->right = g_object_ref (right);
- binary->operation_index = id;
-
- vivi_code_value_set_precedence (VIVI_CODE_VALUE (binary),
- operation_table[id].precedence);
-
- return VIVI_CODE_VALUE (binary);
-}
-
diff --git a/vivified/code/vivi_code_binary.h b/vivified/code/vivi_code_binary.h
index cd71f97..b11cd03 100644
--- a/vivified/code/vivi_code_binary.h
+++ b/vivified/code/vivi_code_binary.h
@@ -20,6 +20,7 @@
#ifndef _VIVI_CODE_BINARY_H_
#define _VIVI_CODE_BINARY_H_
+#include <swfdec/swfdec_as_interpret.h>
#include <vivified/code/vivi_code_value.h>
G_BEGIN_DECLS
@@ -39,7 +40,6 @@ struct _ViviCodeBinary
{
ViviCodeValue parent;
- guint operation_index;
ViviCodeValue * left;
ViviCodeValue * right;
};
@@ -47,16 +47,15 @@ struct _ViviCodeBinary
struct _ViviCodeBinaryClass
{
ViviCodeValueClass value_class;
+
+ /*< private >*/
+ /* use vivi_code_default.h */
+ const char * operator_name;
+ SwfdecAsAction bytecode;
};
GType vivi_code_binary_get_type (void);
-ViviCodeValue * vivi_code_binary_new_bytecode (ViviCodeValue * left,
- ViviCodeValue * right,
- guint code);
-ViviCodeValue * vivi_code_binary_new_name (ViviCodeValue * left,
- ViviCodeValue * right,
- const char * name);
G_END_DECLS
#endif
diff --git a/vivified/code/vivi_code_binary_default.c b/vivified/code/vivi_code_binary_default.c
new file mode 100644
index 0000000..dbb3ba4
--- /dev/null
+++ b/vivified/code/vivi_code_binary_default.c
@@ -0,0 +1,62 @@
+/* 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 <swfdec/swfdec_as_interpret.h>
+
+#include "vivi_code_binary_default.h"
+
+#define DEFAULT_BINARY(CapsName, underscore_name, operatorname, bc, precedence) \
+\
+G_DEFINE_TYPE (ViviCode ## CapsName, vivi_code_ ## underscore_name, VIVI_TYPE_CODE_BINARY) \
+\
+static void \
+vivi_code_ ## underscore_name ## _class_init (ViviCodeBinaryClass *klass) \
+{ \
+ ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass); \
+\
+ binary_class->operator_name = operatorname; \
+ binary_class->bytecode = bc; \
+} \
+\
+static void \
+vivi_code_ ## underscore_name ## _init (ViviCodeBinary *binary) \
+{ \
+ vivi_code_value_set_precedence (VIVI_CODE_VALUE (binary), precedence); \
+} \
+\
+ViviCodeValue * \
+vivi_code_ ## underscore_name ## _new (ViviCodeValue *left, ViviCodeValue *right) \
+{ \
+ ViviCodeBinary *binary; \
+\
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL); \
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL); \
+\
+ binary = g_object_new (vivi_code_ ## underscore_name ## _get_type (), NULL); \
+ binary->left = g_object_ref (left); \
+ binary->right = g_object_ref (right); \
+\
+ return VIVI_CODE_VALUE (binary); \
+}
+
+#include "vivi_code_defaults.h"
diff --git a/vivified/code/vivi_code_binary_default.h b/vivified/code/vivi_code_binary_default.h
new file mode 100644
index 0000000..18a4926
--- /dev/null
+++ b/vivified/code/vivi_code_binary_default.h
@@ -0,0 +1,41 @@
+/* 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_BINARY_DEFAULT_H_
+#define _VIVI_CODE_BINARY_DEFAULT_H_
+
+#include <vivified/code/vivi_code_binary.h>
+
+G_BEGIN_DECLS
+
+#define DEFAULT_BINARY(CapsName, underscore_name, operator_name, bytecode, precedence) \
+\
+typedef ViviCodeBinary ViviCode ## CapsName; \
+typedef ViviCodeBinaryClass ViviCode ## CapsName ## Class; \
+\
+GType vivi_code_ ## underscore_name ## _get_type (void); \
+\
+ViviCodeValue * vivi_code_## underscore_name ## _new (ViviCodeValue * left, \
+ ViviCodeValue * right);
+
+#include "vivi_code_defaults.h"
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_defaults.h b/vivified/code/vivi_code_defaults.h
new file mode 100644
index 0000000..c6d3d45
--- /dev/null
+++ b/vivified/code/vivi_code_defaults.h
@@ -0,0 +1,52 @@
+/* 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 DEFAULT_BINARY
+#define DEFAULT_BINARY(CapsName, underscore_name, operator_name, bytecode, precedence)
+#endif
+
+DEFAULT_BINARY (Add, add, "add", SWFDEC_AS_ACTION_ADD, VIVI_PRECEDENCE_ADD)
+DEFAULT_BINARY (Subtract, subtract, "-", SWFDEC_AS_ACTION_SUBTRACT, VIVI_PRECEDENCE_ADD)
+DEFAULT_BINARY (Multiply, multiply, "*", SWFDEC_AS_ACTION_MULTIPLY, VIVI_PRECEDENCE_MULTIPLY)
+DEFAULT_BINARY (Divide, divide, "/", SWFDEC_AS_ACTION_DIVIDE, VIVI_PRECEDENCE_MULTIPLY)
+DEFAULT_BINARY (Modulo, modulo, "%", SWFDEC_AS_ACTION_MODULO, VIVI_PRECEDENCE_MODULO)
+DEFAULT_BINARY (Equals, equals, "==", SWFDEC_AS_ACTION_EQUALS, VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (Less, less, "<", SWFDEC_AS_ACTION_LESS, VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (LogicalAnd, logical_and, "and", SWFDEC_AS_ACTION_AND, VIVI_PRECEDENCE_AND)
+DEFAULT_BINARY (LogicalOr, logical_or, "or", SWFDEC_AS_ACTION_OR, VIVI_PRECEDENCE_OR)
+DEFAULT_BINARY (StringEquals, string_equals, "eq", SWFDEC_AS_ACTION_STRING_EQUALS, VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (StringLess, string_less, "lt", SWFDEC_AS_ACTION_STRING_LESS, VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (Add2, add2, "+", SWFDEC_AS_ACTION_ADD2, VIVI_PRECEDENCE_ADD)
+DEFAULT_BINARY (Less2, less2, "<", SWFDEC_AS_ACTION_LESS2, VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (Equals2, equals2, "==", SWFDEC_AS_ACTION_EQUALS2, VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (BitwiseAnd, bitwise_and, "&", SWFDEC_AS_ACTION_BIT_AND, VIVI_PRECEDENCE_BINARY_AND)
+DEFAULT_BINARY (BitwiseOr, bitwise_or, "|", SWFDEC_AS_ACTION_BIT_OR, VIVI_PRECEDENCE_BINARY_OR)
+DEFAULT_BINARY (BitwiseXor, bitwise_xor, "^", SWFDEC_AS_ACTION_BIT_XOR, VIVI_PRECEDENCE_BINARY_XOR)
+DEFAULT_BINARY (LeftShift, left_shift, "<<", SWFDEC_AS_ACTION_BIT_LSHIFT, VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (RightShift, right_shift, ">>", SWFDEC_AS_ACTION_BIT_RSHIFT, VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (UnsignedRightShift,unsigned_right_shift,">>>",SWFDEC_AS_ACTION_BIT_URSHIFT,VIVI_PRECEDENCE_SHIFT)
+DEFAULT_BINARY (StrictEquals, strict_equals, "===", SWFDEC_AS_ACTION_STRICT_EQUALS, VIVI_PRECEDENCE_EQUALITY)
+DEFAULT_BINARY (Greater, greater, ">", SWFDEC_AS_ACTION_GREATER, VIVI_PRECEDENCE_RELATIONAL)
+DEFAULT_BINARY (StringGreater, string_greater, "gt", SWFDEC_AS_ACTION_STRING_GREATER,VIVI_PRECEDENCE_RELATIONAL)
+/* other special ones:
+DEFAULT_BINARY (And, and, "&&", ???, VIVI_PRECEDENCE_AND)
+DEFAULT_BINARY (Or, or, "||", ???, VIVI_PRECEDENCE_AND)
+*/
+
+#undef DEFAULT_BINARY
diff --git a/vivified/code/vivi_code_or.c b/vivified/code/vivi_code_or.c
new file mode 100644
index 0000000..ae215bf
--- /dev/null
+++ b/vivified/code/vivi_code_or.c
@@ -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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vivi_code_or.h"
+
+G_DEFINE_TYPE (ViviCodeOr, vivi_code_or, VIVI_TYPE_CODE_BINARY)
+
+static void
+vivi_code_or_class_init (ViviCodeOrClass *klass)
+{
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+ ViviCodeBinaryClass *binary_class = VIVI_CODE_BINARY_CLASS (klass);
+
+ token_class->compile = NULL; /* FIXME */
+
+ binary_class->operator_name = "&&";
+}
+
+static void
+vivi_code_or_init (ViviCodeOr *and)
+{
+ vivi_code_value_set_precedence (VIVI_CODE_VALUE (and), VIVI_PRECEDENCE_AND);
+}
+
+ViviCodeValue *
+vivi_code_or_new (ViviCodeValue *left, ViviCodeValue *right)
+{
+ ViviCodeBinary *binary;
+
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (left), NULL);
+ g_return_val_if_fail (VIVI_IS_CODE_VALUE (right), NULL);
+
+ binary = g_object_new (VIVI_TYPE_CODE_OR, NULL);
+ binary->left = g_object_ref (left);
+ binary->right = g_object_ref (right);
+
+ return VIVI_CODE_VALUE (binary);
+}
+
diff --git a/vivified/code/vivi_code_or.h b/vivified/code/vivi_code_or.h
new file mode 100644
index 0000000..583bc77
--- /dev/null
+++ b/vivified/code/vivi_code_or.h
@@ -0,0 +1,55 @@
+/* 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_OR_H_
+#define _VIVI_CODE_OR_H_
+
+#include <vivified/code/vivi_code_binary.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _ViviCodeOr ViviCodeOr;
+typedef struct _ViviCodeOrClass ViviCodeOrClass;
+
+#define VIVI_TYPE_CODE_OR (vivi_code_or_get_type())
+#define VIVI_IS_CODE_OR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_OR))
+#define VIVI_IS_CODE_OR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_OR))
+#define VIVI_CODE_OR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_OR, ViviCodeOr))
+#define VIVI_CODE_OR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_OR, ViviCodeOrClass))
+#define VIVI_CODE_OR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_OR, ViviCodeOrClass))
+
+struct _ViviCodeOr
+{
+ ViviCodeBinary binary;
+};
+
+struct _ViviCodeOrClass
+{
+ ViviCodeBinaryClass binary_class;
+};
+
+GType vivi_code_or_get_type (void);
+
+ViviCodeValue * vivi_code_or_new (ViviCodeValue * left,
+ ViviCodeValue * right);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_code_value.h b/vivified/code/vivi_code_value.h
index ae66a9c..61ea81a 100644
--- a/vivified/code/vivi_code_value.h
+++ b/vivified/code/vivi_code_value.h
@@ -38,6 +38,7 @@ typedef enum {
VIVI_PRECEDENCE_RELATIONAL,
VIVI_PRECEDENCE_SHIFT,
VIVI_PRECEDENCE_ADD,
+ VIVI_PRECEDENCE_MODULO,
VIVI_PRECEDENCE_MULTIPLY,
VIVI_PRECEDENCE_UNARY,
VIVI_PRECEDENCE_INCREMENT,
diff --git a/vivified/code/vivi_decompiler.c b/vivified/code/vivi_decompiler.c
index d4b5759..fc63fb0 100644
--- a/vivified/code/vivi_decompiler.c
+++ b/vivified/code/vivi_decompiler.c
@@ -28,8 +28,9 @@
#include <swfdec/swfdec_script_internal.h>
#include "vivi_decompiler.h"
+#include "vivi_code_and.h"
#include "vivi_code_assignment.h"
-#include "vivi_code_binary.h"
+#include "vivi_code_binary_default.h"
#include "vivi_code_block.h"
#include "vivi_code_break.h"
#include "vivi_code_constant.h"
@@ -42,6 +43,7 @@
#include "vivi_code_if.h"
#include "vivi_code_init_object.h"
#include "vivi_code_loop.h"
+#include "vivi_code_or.h"
#include "vivi_code_return.h"
#include "vivi_code_trace.h"
#include "vivi_code_unary.h"
@@ -402,10 +404,19 @@ vivi_decompile_binary (ViviDecompilerBlock *block, ViviDecompilerState *state,
guint code, const guint8 *data, guint len)
{
ViviCodeValue *right, *left, *result;
+#define DEFAULT_BINARY(CapsName, underscore_name, operatore_name, bytecode, precedence) \
+ case bytecode: \
+ result = vivi_code_ ## underscore_name ## _new (left, right); \
+ break;
right = vivi_decompiler_state_pop (state);
left = vivi_decompiler_state_pop (state);
- result = vivi_code_binary_new_bytecode (left, right, code);
+ switch (code) {
+#include "vivi_code_defaults.h"
+ default:
+ g_assert_not_reached ();
+ return FALSE;
+ }
g_object_unref (left);
g_object_unref (right);
vivi_decompiler_state_push (state, result);
@@ -1062,9 +1073,9 @@ vivi_decompiler_merge_andor (GList **list)
{
ViviDecompilerBlock *block, *andor, *next;
gboolean result;
- const char *type;
ViviCodeValue *value, *value2;
ViviDecompilerState *state;
+ ViviCodeValue * (* func) (ViviCodeValue *, ViviCodeValue *);
GList *walk;
result = FALSE;
@@ -1087,9 +1098,9 @@ vivi_decompiler_merge_andor (GList **list)
value = vivi_decompiler_block_get_branch_condition (block);
if (VIVI_IS_CODE_UNARY (value)) {
value = vivi_code_unary_get_value (VIVI_CODE_UNARY (value));
- type = "&&";
+ func = vivi_code_and_new;
} else {
- type = "||";
+ func = vivi_code_or_new;
}
if (!VIVI_IS_DECOMPILER_DUPLICATE (value))
continue;
@@ -1121,7 +1132,7 @@ vivi_decompiler_merge_andor (GList **list)
DEBUG ("merging %s code for %p\n", type, vivi_decompiler_block_get_start (andor));
/* update our finish state */
- value = vivi_code_binary_new_name (value, value2, type);
+ value = func (value, value2);
state = (ViviDecompilerState *) vivi_decompiler_block_get_end_state (block);
g_object_unref (vivi_decompiler_state_pop (state));
vivi_decompiler_state_push (state, value);
diff --git a/vivified/code/vivi_parser.c b/vivified/code/vivi_parser.c
index 5423bca..4f37bb6 100644
--- a/vivified/code/vivi_parser.c
+++ b/vivified/code/vivi_parser.c
@@ -27,8 +27,9 @@
#include "vivi_parser_scanner.h"
+#include "vivi_code_and.h"
#include "vivi_code_assignment.h"
-#include "vivi_code_binary.h"
+#include "vivi_code_binary_default.h"
#include "vivi_code_block.h"
#include "vivi_code_break.h"
#include "vivi_code_constant.h"
@@ -42,6 +43,7 @@
#include "vivi_code_init_array.h"
#include "vivi_code_init_object.h"
#include "vivi_code_loop.h"
+#include "vivi_code_or.h"
#include "vivi_code_play.h"
#include "vivi_code_return.h"
#include "vivi_code_throw.h"
@@ -1278,7 +1280,7 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
{
ViviCodeStatement *assignment;
ViviCodeValue *operation, *one, *temporary;
- const char *operator;
+ gboolean add;
vivi_parser_start_code_token (data);
@@ -1290,9 +1292,9 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
}
if (try_parse_token (data, TOKEN_INCREASE)) {
- operator = "+";
+ add = TRUE;
} else if (try_parse_token (data, TOKEN_DESCREASE)) {
- operator = "-";
+ add = FALSE;
} else {
vivi_parser_end_code_token (data, NULL);
return;
@@ -1305,7 +1307,7 @@ parse_postfix_expression (ParseData *data, ViviCodeValue **value,
}
one = vivi_code_constant_new_number (1);
- operation = vivi_code_binary_new_name (*value, one, operator);
+ operation = (add ? vivi_code_add_new : vivi_code_subtract_new) (*value, one);
g_object_unref (one);
vivi_parser_duplicate_code_token (data);
@@ -1352,9 +1354,6 @@ parse_unary_expression (ParseData *data, ViviCodeValue **value,
ViviCodeStatement **statement)
{
ViviCodeValue *tmp, *one;
- const char *operator;
-
- operator = NULL;
vivi_parser_scanner_peek_next_token (data->scanner);
switch ((guint)data->scanner->next_token) {
@@ -1362,11 +1361,7 @@ parse_unary_expression (ParseData *data, ViviCodeValue **value,
case TOKEN_VOID:
case TOKEN_TYPEOF:*/
case TOKEN_INCREASE:
- operator = "+";
- // fall through
case TOKEN_DESCREASE:
- if (!operator) operator = "-";
-
vivi_parser_start_code_token (data);
vivi_parser_scanner_get_next_token (data->scanner);
@@ -1380,7 +1375,7 @@ parse_unary_expression (ParseData *data, ViviCodeValue **value,
}
one = vivi_code_constant_new_number (1);
- tmp = vivi_code_binary_new_name (*value, one, operator);
+ tmp = (data->scanner->next_token == TOKEN_INCREASE ? vivi_code_add_new : vivi_code_subtract_new) (*value, one);
g_object_unref (one);
vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (tmp));
@@ -1424,7 +1419,37 @@ parse_operator_expression (ParseData *data, ViviCodeValue **value,
{
ViviCodeValue *left, *right;
ViviCodeStatement *statement_right;
- guint i;
+ guint i, j;
+ static const struct {
+ ViviParserScannerToken token;
+ ViviCodeValue * (* func) (ViviCodeValue *, ViviCodeValue *);
+ } table[] = {
+// { TOKEN_, vivi_code_add_new },
+ { TOKEN_MINUS, vivi_code_subtract_new },
+ { TOKEN_MULTIPLY, vivi_code_multiply_new },
+ { TOKEN_DIVIDE, vivi_code_divide_new },
+ { TOKEN_REMAINDER, vivi_code_modulo_new },
+// { TOKEN_, vivi_code_equals_new },
+// { TOKEN_, vivi_code_less_new },
+// { TOKEN_, vivi_code_logical_and_new },
+// { TOKEN_, vivi_code_logical_or_new },
+// { TOKEN_, vivi_code_string_equals_new },
+// { TOKEN_, vivi_code_string_less_new },
+ { TOKEN_PLUS, vivi_code_add2_new },
+ { TOKEN_LESS_THAN, vivi_code_less2_new },
+ { TOKEN_EQUAL, vivi_code_equals2_new },
+ { TOKEN_BITWISE_AND, vivi_code_bitwise_and_new },
+ { TOKEN_BITWISE_OR, vivi_code_bitwise_or_new },
+ { TOKEN_BITWISE_XOR, vivi_code_bitwise_xor_new },
+ { TOKEN_SHIFT_LEFT, vivi_code_left_shift_new },
+ { TOKEN_SHIFT_RIGHT, vivi_code_right_shift_new },
+ { TOKEN_SHIFT_RIGHT_UNSIGNED, vivi_code_unsigned_right_shift_new },
+ { TOKEN_STRICT_EQUAL, vivi_code_strict_equals_new },
+ { TOKEN_GREATER_THAN, vivi_code_greater_new },
+// { TOKEN_, vivi_code_string_greater_new },
+ { TOKEN_LOGICAL_AND, vivi_code_and_new },
+ { TOKEN_LOGICAL_OR, vivi_code_or_new }
+ };
vivi_parser_start_code_token (data);
@@ -1462,15 +1487,20 @@ again:
}
left = VIVI_CODE_VALUE (*value);
- *value = vivi_code_binary_new_name (left, VIVI_CODE_VALUE (right),
- vivi_parser_scanner_token_name (tokens[i]));
- g_object_unref (left);
- g_object_unref (right);
+ for (j = 0; j < G_N_ELEMENTS (table); j++) {
+ if (tokens[i] != table[j].token)
+ continue;
- vivi_parser_duplicate_code_token (data);
- vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
+ *value = table[j].func (left, VIVI_CODE_VALUE (right));
+ g_object_unref (left);
+ g_object_unref (right);
- goto again;
+ vivi_parser_duplicate_code_token (data);
+ vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (*value));
+
+ goto again;
+ }
+ g_assert_not_reached ();
}
}
@@ -1711,7 +1741,7 @@ parse_assignment_expression (ParseData *data, ViviCodeValue **value,
{
ViviCodeValue *right;
ViviCodeStatement *assignment, *statement_right;
- const char *operator;
+ ViviCodeValue * (* func) (ViviCodeValue *, ViviCodeValue *);
vivi_parser_start_code_token (data);
@@ -1723,53 +1753,64 @@ parse_assignment_expression (ParseData *data, ViviCodeValue **value,
return;
}
- operator = NULL;
-
vivi_parser_scanner_peek_next_token (data->scanner);
switch ((guint)data->scanner->next_token) {
case TOKEN_ASSIGN_MULTIPLY:
- if (operator == NULL) operator = "*";
+ func = vivi_code_multiply_new;
+ break;
case TOKEN_ASSIGN_DIVIDE:
- if (operator == NULL) operator = "/";
+ func = vivi_code_divide_new;
+ break;
case TOKEN_ASSIGN_REMAINDER:
- if (operator == NULL) operator = "%";
+ func = vivi_code_modulo_new;
+ break;
case TOKEN_ASSIGN_ADD:
- if (operator == NULL) operator = "+";
+ func = vivi_code_add2_new;
+ break;
case TOKEN_ASSIGN_MINUS:
- if (operator == NULL) operator = "-";
+ func = vivi_code_subtract_new;
+ break;
case TOKEN_ASSIGN_SHIFT_LEFT:
- if (operator == NULL) operator = "<<";
+ func = vivi_code_left_shift_new;
+ break;
case TOKEN_ASSIGN_SHIFT_RIGHT:
- if (operator == NULL) operator = ">>";
+ func = vivi_code_right_shift_new;
+ break;
case TOKEN_ASSIGN_SHIFT_RIGHT_ZERO:
- if (operator == NULL) operator = ">>>";
+ func = vivi_code_unsigned_right_shift_new;
+ break;
case TOKEN_ASSIGN_BITWISE_AND:
- if (operator == NULL) operator = "&";
+ func = vivi_code_bitwise_and_new;
+ break;
case TOKEN_ASSIGN_BITWISE_OR:
- if (operator == NULL) operator = "|";
+ func = vivi_code_bitwise_or_new;
+ break;
case TOKEN_ASSIGN_BITWISE_XOR:
- if (operator == NULL) operator = "^";
+ func = vivi_code_bitwise_and_new;
+ break;
case TOKEN_ASSIGN:
- vivi_parser_scanner_get_next_token (data->scanner);
+ func = NULL;
+ break;
+ default:
+ return;
+ }
+
+ vivi_parser_scanner_get_next_token (data->scanner);
- parse_assignment_expression (data, &right, &statement_right);
+ parse_assignment_expression (data, &right, &statement_right);
- if (operator != NULL) {
- assignment = vivi_parser_assignment_new (*value,
- vivi_code_binary_new_name (*value, right, operator));
- } else {
- assignment = vivi_parser_assignment_new (*value, right);
- }
- g_object_unref (right);
+ if (func != NULL) {
+ assignment = vivi_parser_assignment_new (*value,
+ func (*value, right));
+ } else {
+ assignment = vivi_parser_assignment_new (*value, right);
+ }
+ g_object_unref (right);
- vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (assignment));
+ vivi_parser_end_code_token (data, VIVI_CODE_TOKEN (assignment));
- *statement = vivi_parser_join_statements (*statement,
- vivi_parser_join_statements (statement_right, assignment));
- break;
- default:
- break;
- }
+ *statement = vivi_parser_join_statements (*statement,
+ vivi_parser_join_statements (statement_right, assignment));
}
static gboolean
More information about the Swfdec-commits
mailing list