[Swfdec-commits] 6 commits - swfdec/swfdec_as_context.c swfdec/swfdec_as_frame.c swfdec/swfdec_as_frame_internal.h swfdec/swfdec_as_interpret.c test/trace vivified/code
Pekka Lampila
medar at kemper.freedesktop.org
Fri Apr 25 06:38:59 PDT 2008
swfdec/swfdec_as_context.c | 2
swfdec/swfdec_as_frame.c | 18 +
swfdec/swfdec_as_frame_internal.h | 8
swfdec/swfdec_as_interpret.c | 66 +----
test/trace/Makefile.am | 27 ++
test/trace/definelocal-overwrite-5.swf |binary
test/trace/definelocal-overwrite-5.swf.trace | 3
test/trace/definelocal-overwrite-6.swf |binary
test/trace/definelocal-overwrite-6.swf.trace | 3
test/trace/definelocal-overwrite-7.swf |binary
test/trace/definelocal-overwrite-7.swf.trace | 3
test/trace/definelocal-overwrite-8.swf |binary
test/trace/definelocal-overwrite-8.swf.trace | 3
test/trace/definelocal-overwrite.as | 10
test/trace/definelocal-scope-5.swf |binary
test/trace/definelocal-scope-5.swf.trace | 8
test/trace/definelocal-scope-6.swf |binary
test/trace/definelocal-scope-6.swf.trace | 8
test/trace/definelocal-scope-7.swf |binary
test/trace/definelocal-scope-7.swf.trace | 8
test/trace/definelocal-scope-8.swf |binary
test/trace/definelocal-scope-8.swf.trace | 8
test/trace/definelocal-scope.as | 37 ++
test/trace/too-many-blocks-5.swf |binary
test/trace/too-many-blocks-5.swf.trace | 4
test/trace/too-many-blocks-6.swf |binary
test/trace/too-many-blocks-6.swf.trace | 4
test/trace/too-many-blocks-7.swf |binary
test/trace/too-many-blocks-7.swf.trace | 4
test/trace/too-many-blocks-8.swf |binary
test/trace/too-many-blocks-8.swf.trace | 4
test/trace/too-many-blocks.as | 25 +
vivified/code/Makefile.am | 2
vivified/code/vivi_code_asm_try.c | 341 +++++++++++++++++++++++++++
vivified/code/vivi_code_asm_try.h | 84 ++++++
vivified/code/vivi_disassembler.c | 56 ++++
36 files changed, 684 insertions(+), 52 deletions(-)
New commits:
commit f6de7efe91acf624df8a7c5de1386dc713058ccc
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 25 16:37:28 2008 +0300
Implement ViviCodeAsmTry and deassembler for it
diff --git a/vivified/code/Makefile.am b/vivified/code/Makefile.am
index 2c22c85..8a642cd 100644
--- a/vivified/code/Makefile.am
+++ b/vivified/code/Makefile.am
@@ -28,6 +28,7 @@ libvivified_compiler_la_SOURCES = \
vivi_code_asm_pool.c \
vivi_code_asm_push.c \
vivi_code_asm_store.c \
+ vivi_code_asm_try.c \
vivi_code_asm_with.c \
vivi_code_assembler.c \
vivi_code_assignment.c \
@@ -100,6 +101,7 @@ noinst_HEADERS = \
vivi_code_asm_pool.h \
vivi_code_asm_push.h \
vivi_code_asm_store.h \
+ vivi_code_asm_try.h \
vivi_code_asm_with.h \
vivi_code_assembler.h \
vivi_code_assignment.h \
diff --git a/vivified/code/vivi_code_asm_try.c b/vivified/code/vivi_code_asm_try.c
new file mode 100644
index 0000000..3782582
--- /dev/null
+++ b/vivified/code/vivi_code_asm_try.c
@@ -0,0 +1,341 @@
+/* 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 <string.h>
+
+#include <swfdec/swfdec_as_interpret.h>
+#include <swfdec/swfdec_bits.h>
+
+#include "vivi_code_asm_try.h"
+#include "vivi_code_asm.h"
+#include "vivi_code_emitter.h"
+#include "vivi_code_error.h"
+#include "vivi_code_printer.h"
+
+static gboolean
+vivi_code_asm_try_resolve (ViviCodeEmitter *emitter, SwfdecBuffer *buffer,
+ gsize offset, gpointer data, GError **error)
+{
+ ViviCodeAsmTry *try_ = VIVI_CODE_ASM_TRY (data);
+ gssize catch_start_offset, finally_start_offset, end_offset;
+ gsize write_offset, diff;
+
+ write_offset = offset;
+
+ if (try_->use_register) {
+ offset += 1;
+ } else {
+ offset += strlen (try_->variable_name) + 1;
+ }
+
+ catch_start_offset =
+ vivi_code_emitter_get_label_offset (emitter, try_->catch_start);
+ if (catch_start_offset < 0) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_MISSING_LABEL,
+ "no label \"%s\"", vivi_code_label_get_name (try_->catch_start));
+ return FALSE;
+ }
+
+ finally_start_offset =
+ vivi_code_emitter_get_label_offset (emitter, try_->finally_start);
+ if (finally_start_offset < 0) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_MISSING_LABEL,
+ "no label \"%s\"", vivi_code_label_get_name (try_->finally_start));
+ return FALSE;
+ }
+
+ end_offset = vivi_code_emitter_get_label_offset (emitter, try_->end);
+ if (end_offset < 0) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_MISSING_LABEL,
+ "no label \"%s\"", vivi_code_label_get_name (try_->end));
+ return FALSE;
+ }
+
+ if ((gsize)catch_start_offset < offset) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_SIZE,
+ "catch start before try");
+ return FALSE;
+ }
+
+ if (finally_start_offset < catch_start_offset) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_SIZE,
+ "finally start before catch start");
+ return FALSE;
+ }
+
+ if (end_offset < finally_start_offset) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_SIZE,
+ "end before finally start");
+ return FALSE;
+ }
+
+ // try size
+ diff = catch_start_offset - offset;
+ if (diff > G_MAXUINT16) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_SIZE,
+ "catch start too far away");
+ return FALSE;
+ }
+
+ buffer->data[write_offset - 5] = diff >> 8;
+ buffer->data[write_offset - 6] = diff;
+
+ // catch size
+ diff = finally_start_offset - catch_start_offset;
+ if (diff > G_MAXUINT16) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_SIZE,
+ "finally start too far away");
+ return FALSE;
+ }
+
+ buffer->data[write_offset - 3] = diff >> 8;
+ buffer->data[write_offset - 4] = diff;
+
+ // finally size
+ diff = end_offset - finally_start_offset;
+ if (diff > G_MAXUINT16) {
+ g_set_error (error, VIVI_CODE_ERROR, VIVI_CODE_ERROR_SIZE,
+ "end too far away");
+ return FALSE;
+ }
+
+ buffer->data[write_offset - 1] = diff >> 8;
+ buffer->data[write_offset - 2] = diff;
+
+ return TRUE;
+}
+
+static gboolean
+vivi_code_asm_try_emit (ViviCodeAsm *code, ViviCodeEmitter *emitter,
+ GError **error)
+{
+ ViviCodeAsmTry *try_ = VIVI_CODE_ASM_TRY (code);
+ SwfdecBots *emit = vivi_code_emitter_get_bots (emitter);
+ guint flags;
+
+ swfdec_bots_put_u8 (emit, SWFDEC_AS_ACTION_TRY);
+ swfdec_bots_put_u16 (emit,
+ 8 + (try_->use_register ? 0 : strlen (try_->variable_name)));
+
+ flags = try_->reserved_flags << 3;
+ if (try_->has_catch) {
+ flags |= (1 << 0);
+ } else {
+ flags &= ~(1 << 0);
+ }
+ if (try_->has_finally) {
+ flags |= (1 << 1);
+ } else {
+ flags &= ~(1 << 1);
+ }
+ if (try_->use_register) {
+ flags |= (1 << 2);
+ } else {
+ flags &= ~(1 << 2);
+ }
+ swfdec_bots_put_u8 (emit, flags);
+
+ swfdec_bots_put_u16 (emit, 0); /* try size */
+ swfdec_bots_put_u16 (emit, 0); /* catch size */
+ swfdec_bots_put_u16 (emit, 0); /* finally size */
+ vivi_code_emitter_add_later (emitter, vivi_code_asm_try_resolve, code);
+
+ if (try_->use_register) {
+ swfdec_bots_put_u8 (emit, try_->register_number);
+ } else {
+ swfdec_bots_put_string (emit, try_->variable_name);
+ }
+
+ return TRUE;
+}
+
+static void
+vivi_code_asm_try_asm_init (ViviCodeAsmInterface *iface)
+{
+ iface->emit = vivi_code_asm_try_emit;
+}
+
+G_DEFINE_TYPE_WITH_CODE (ViviCodeAsmTry, vivi_code_asm_try, VIVI_TYPE_CODE_ASM_CODE,
+ G_IMPLEMENT_INTERFACE (VIVI_TYPE_CODE_ASM, vivi_code_asm_try_asm_init))
+
+static void
+vivi_code_asm_try_print (ViviCodeToken *token, ViviCodePrinter *printer)
+{
+ ViviCodeAsmTry *try_ = VIVI_CODE_ASM_TRY (token);
+ guint i;
+
+ vivi_code_printer_print (printer, "try ");
+
+ if (try_->has_catch)
+ vivi_code_printer_print (printer, "has_catch ");
+
+ if (try_->has_finally)
+ vivi_code_printer_print (printer, "has_finally ");
+
+ if (try_->use_register)
+ vivi_code_printer_print (printer, "use_register ");
+
+ for (i = 0; i < 5; i++) {
+ if (try_->reserved_flags & (1 << i)) {
+ char *str = g_strdup_printf ("reserverd%i ", i + 1);
+ vivi_code_printer_print (printer, str);
+ g_free (str);
+ }
+ }
+
+ if (try_->use_register) {
+ char *str = g_strdup_printf ("%i", try_->register_number);
+ vivi_code_printer_print (printer, str);
+ g_free (str);
+ } else {
+ vivi_code_printer_print (printer, try_->variable_name);
+ }
+ vivi_code_printer_print (printer, " ");
+
+ vivi_code_printer_print (printer,
+ vivi_code_label_get_name (try_->catch_start));
+ vivi_code_printer_print (printer, " ");
+
+ vivi_code_printer_print (printer,
+ vivi_code_label_get_name (try_->finally_start));
+ vivi_code_printer_print (printer, " ");
+
+ vivi_code_printer_print (printer, vivi_code_label_get_name (try_->end));
+
+ vivi_code_printer_new_line (printer, FALSE);
+}
+
+static void
+vivi_code_asm_try_dispose (GObject *object)
+{
+ ViviCodeAsmTry *try_ = VIVI_CODE_ASM_TRY (object);
+
+ if (!try_->use_register)
+ g_free (try_->variable_name);
+
+ g_object_unref (try_->catch_start);
+ g_object_unref (try_->finally_start);
+ g_object_unref (try_->end);
+
+ G_OBJECT_CLASS (vivi_code_asm_try_parent_class)->dispose (object);
+}
+
+static void
+vivi_code_asm_try_class_init (ViviCodeAsmTryClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ViviCodeTokenClass *token_class = VIVI_CODE_TOKEN_CLASS (klass);
+ ViviCodeAsmCodeClass *code_class = VIVI_CODE_ASM_CODE_CLASS (klass);
+
+ object_class->dispose = vivi_code_asm_try_dispose;
+
+ token_class->print = vivi_code_asm_try_print;
+
+ code_class->bytecode = SWFDEC_AS_ACTION_TRY;
+}
+
+static void
+vivi_code_asm_try_init (ViviCodeAsmTry *try_)
+{
+}
+
+static ViviCodeAsmTry *
+vivi_code_asm_try_new_internal (gboolean has_catch, gboolean has_finally,
+ ViviCodeLabel *catch_start, ViviCodeLabel *finally_start,
+ ViviCodeLabel *end)
+{
+ ViviCodeAsmTry *ret;
+
+ g_return_val_if_fail (VIVI_IS_CODE_LABEL (catch_start), NULL);
+ g_return_val_if_fail (VIVI_IS_CODE_LABEL (finally_start), NULL);
+ g_return_val_if_fail (VIVI_IS_CODE_LABEL (end), NULL);
+
+ ret = g_object_new (VIVI_TYPE_CODE_ASM_TRY, NULL);
+ ret->catch_start = g_object_ref (catch_start);
+ ret->finally_start = g_object_ref (finally_start);
+ ret->end = g_object_ref (end);
+
+ ret->has_catch = has_catch;
+ ret->has_finally = has_finally;
+ ret->reserved_flags = 0;
+
+ return ret;
+}
+
+ViviCodeAsm *
+vivi_code_asm_try_new_variable (const char *name, gboolean has_catch,
+ gboolean has_finally, ViviCodeLabel *catch_start,
+ ViviCodeLabel *finally_start, ViviCodeLabel *end)
+{
+ ViviCodeAsmTry *try_;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ try_ = vivi_code_asm_try_new_internal (has_catch, has_finally, catch_start,
+ finally_start, end);
+ try_->use_register = FALSE;
+ try_->variable_name = g_strdup (name);
+
+ return VIVI_CODE_ASM (try_);
+}
+
+ViviCodeAsm *
+vivi_code_asm_try_new_register (guint register_number, gboolean has_catch,
+ gboolean has_finally, ViviCodeLabel *catch_start,
+ ViviCodeLabel *finally_start, ViviCodeLabel *end)
+{
+ ViviCodeAsmTry *try_;
+
+ g_return_val_if_fail (register_number < 256, NULL);
+
+ try_ = vivi_code_asm_try_new_internal (has_catch, has_finally, catch_start,
+ finally_start, end);
+ try_->use_register = TRUE;
+ try_->register_number = register_number;
+
+ return VIVI_CODE_ASM (try_);
+}
+
+void
+vivi_code_asm_try_set_reserved_flags (ViviCodeAsmTry *try_, guint flags)
+{
+ g_return_if_fail (VIVI_IS_CODE_ASM_TRY (try_));
+ g_return_if_fail (flags < (1 << 5));
+
+ try_->reserved_flags = flags;
+}
+
+void
+vivi_code_asm_try_set_variable_name (ViviCodeAsmTry *try_, const char *name)
+{
+ g_return_if_fail (VIVI_IS_CODE_ASM_TRY (try_));
+ g_return_if_fail (name != NULL);
+
+ if (!try_->use_register) {
+ g_free (try_->variable_name);
+ } else {
+ try_->use_register = FALSE;
+ }
+
+ try_->variable_name = g_strdup (name);
+}
diff --git a/vivified/code/vivi_code_asm_try.h b/vivified/code/vivi_code_asm_try.h
new file mode 100644
index 0000000..c40afcf
--- /dev/null
+++ b/vivified/code/vivi_code_asm_try.h
@@ -0,0 +1,84 @@
+/* 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_ASM_TRY_H_
+#define _VIVI_CODE_ASM_TRY_H_
+
+#include <vivified/code/vivi_code_asm.h>
+#include <vivified/code/vivi_code_asm_code.h>
+#include <vivified/code/vivi_code_label.h>
+
+G_BEGIN_DECLS
+
+typedef struct _ViviCodeAsmTry ViviCodeAsmTry;
+typedef struct _ViviCodeAsmTryClass ViviCodeAsmTryClass;
+
+#define VIVI_TYPE_CODE_ASM_TRY (vivi_code_asm_try_get_type())
+#define VIVI_IS_CODE_ASM_TRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIVI_TYPE_CODE_ASM_TRY))
+#define VIVI_IS_CODE_ASM_TRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIVI_TYPE_CODE_ASM_TRY))
+#define VIVI_CODE_ASM_TRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIVI_TYPE_CODE_ASM_TRY, ViviCodeAsmTry))
+#define VIVI_CODE_ASM_TRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIVI_TYPE_CODE_ASM_TRY, ViviCodeAsmTryClass))
+#define VIVI_CODE_ASM_TRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIVI_TYPE_CODE_ASM_TRTRY ViviCodeAsmTryClass))
+
+struct _ViviCodeAsmTry
+{
+ ViviCodeAsmCode code;
+
+ gboolean has_catch;
+ gboolean has_finally;
+ gboolean use_register;
+ guint reserved_flags;
+ union {
+ guint register_number;
+ char * variable_name;
+ };
+ ViviCodeLabel * catch_start;
+ ViviCodeLabel * finally_start;
+ ViviCodeLabel * end;
+};
+
+struct _ViviCodeAsmTryClass
+{
+ ViviCodeAsmCodeClass code_class;
+};
+
+GType vivi_code_asm_try_get_type (void);
+
+ViviCodeAsm * vivi_code_asm_try_new_variable (const char * name,
+ gboolean has_catch,
+ gboolean has_finally,
+ ViviCodeLabel * catch_start,
+ ViviCodeLabel * finally_start,
+ ViviCodeLabel * end);
+ViviCodeAsm * vivi_code_asm_try_new_register (guint register_number,
+ gboolean has_catch,
+ gboolean has_finally,
+ ViviCodeLabel * catch_start,
+ ViviCodeLabel * finally_start,
+ ViviCodeLabel * end);
+
+void vivi_code_asm_try_set_reserved_flags (ViviCodeAsmTry * try_,
+ guint flags);
+
+void vivi_code_asm_try_set_variable_name (ViviCodeAsmTry * try_,
+ const char * name);
+
+
+G_END_DECLS
+#endif
diff --git a/vivified/code/vivi_disassembler.c b/vivified/code/vivi_disassembler.c
index 2163d6d..69be97c 100644
--- a/vivified/code/vivi_disassembler.c
+++ b/vivified/code/vivi_disassembler.c
@@ -35,6 +35,7 @@
#include "vivi_code_asm_pool.h"
#include "vivi_code_asm_push.h"
#include "vivi_code_asm_store.h"
+#include "vivi_code_asm_try.h"
#include "vivi_code_asm_with.h"
#include "vivi_code_assembler.h"
#include "vivi_code_comment.h"
@@ -379,6 +380,60 @@ vivi_disassemble_script (SwfdecScript *script)
g_object_unref (fun);
}
break;
+ case SWFDEC_AS_ACTION_TRY:
+ {
+ gboolean has_catch, has_finally, use_register;
+ guint flags, try_size, catch_size, finally_size, register_number;
+ char *name;
+ ViviCodeLabel *catch_start, *finally_start, *end_label;
+ ViviCodeAsm *try;
+
+ flags = swfdec_bits_get_u8 (&bits);
+
+ has_catch = flags & (1 << 0);
+ has_finally = flags & (1 << 1);
+ use_register = flags & (1 << 2);
+
+ try_size = swfdec_bits_get_u16 (&bits);
+ catch_size = swfdec_bits_get_u16 (&bits);
+ finally_size = swfdec_bits_get_u16 (&bits);
+ if (use_register) {
+ register_number = swfdec_bits_get_u8 (&bits);
+ name = NULL; // shut up compiler warnings
+ } else {
+ register_number = 0;
+ name = swfdec_bits_get_string (&bits, script->version);
+ }
+
+ end_label = vivi_disassemble_labels_get_label (labels,
+ pc + try_size + catch_size + finally_size);
+ if (finally_size > 0) {
+ finally_start = vivi_disassemble_labels_get_label (labels,
+ pc + try_size + catch_size);
+ } else {
+ finally_start = end_label;
+ }
+ if (catch_size > 0) {
+ catch_start = vivi_disassemble_labels_get_label (labels,
+ pc + try_size);
+ } else {
+ catch_start = finally_start;
+ }
+
+ if (use_register) {
+ try = vivi_code_asm_try_new_register (register_number,
+ has_catch, has_finally, catch_start, finally_start,
+ end_label);
+ } else {
+ try = vivi_code_asm_try_new_variable (name, has_catch,
+ has_finally, catch_start, finally_start, end_label);
+ g_free (name);
+ }
+ vivi_code_asm_try_set_reserved_flags (VIVI_CODE_ASM_TRY (try),
+ flags >> 3);
+ vivi_code_assembler_add_code (assembler, try);
+ }
+ break;
case SWFDEC_AS_ACTION_GET_URL:
vivi_disassemble_get_url (assembler, &bits, script->version);
break;
@@ -388,7 +443,6 @@ vivi_disassemble_script (SwfdecScript *script)
case SWFDEC_AS_ACTION_SET_TARGET:
case SWFDEC_AS_ACTION_GOTO_LABEL:
case SWFDEC_AS_ACTION_WAIT_FOR_FRAME2:
- case SWFDEC_AS_ACTION_TRY:
case SWFDEC_AS_ACTION_GET_URL2:
case SWFDEC_AS_ACTION_CALL:
case SWFDEC_AS_ACTION_GOTO_FRAME2:
commit 59908d27b24aae9c4cd3ac1dca1bc88444671297
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 25 16:03:32 2008 +0300
Add a test for DefineLocal with variables of the same name in the scope chain
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 6eaf546..395c1db 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -867,6 +867,15 @@ EXTRA_DIST = \
definelocal-overwrite-7.swf.trace \
definelocal-overwrite-8.swf \
definelocal-overwrite-8.swf.trace \
+ definelocal-scope.as \
+ definelocal-scope-5.swf \
+ definelocal-scope-5.swf.trace \
+ definelocal-scope-6.swf \
+ definelocal-scope-6.swf.trace \
+ definelocal-scope-7.swf \
+ definelocal-scope-7.swf.trace \
+ definelocal-scope-8.swf \
+ definelocal-scope-8.swf.trace \
definelocal-target.as \
definelocal-target-5.swf \
definelocal-target-5.swf.trace \
diff --git a/test/trace/definelocal-scope-5.swf b/test/trace/definelocal-scope-5.swf
new file mode 100644
index 0000000..51e3a97
Binary files /dev/null and b/test/trace/definelocal-scope-5.swf differ
diff --git a/test/trace/definelocal-scope-5.swf.trace b/test/trace/definelocal-scope-5.swf.trace
new file mode 100644
index 0000000..250b2b3
--- /dev/null
+++ b/test/trace/definelocal-scope-5.swf.trace
@@ -0,0 +1,8 @@
+0
+0
+0
+4
+0
+0
+0
+0
diff --git a/test/trace/definelocal-scope-6.swf b/test/trace/definelocal-scope-6.swf
new file mode 100644
index 0000000..d26f1f5
Binary files /dev/null and b/test/trace/definelocal-scope-6.swf differ
diff --git a/test/trace/definelocal-scope-6.swf.trace b/test/trace/definelocal-scope-6.swf.trace
new file mode 100644
index 0000000..250b2b3
--- /dev/null
+++ b/test/trace/definelocal-scope-6.swf.trace
@@ -0,0 +1,8 @@
+0
+0
+0
+4
+0
+0
+0
+0
diff --git a/test/trace/definelocal-scope-7.swf b/test/trace/definelocal-scope-7.swf
new file mode 100644
index 0000000..41bf4fa
Binary files /dev/null and b/test/trace/definelocal-scope-7.swf differ
diff --git a/test/trace/definelocal-scope-7.swf.trace b/test/trace/definelocal-scope-7.swf.trace
new file mode 100644
index 0000000..250b2b3
--- /dev/null
+++ b/test/trace/definelocal-scope-7.swf.trace
@@ -0,0 +1,8 @@
+0
+0
+0
+4
+0
+0
+0
+0
diff --git a/test/trace/definelocal-scope-8.swf b/test/trace/definelocal-scope-8.swf
new file mode 100644
index 0000000..94c72e6
Binary files /dev/null and b/test/trace/definelocal-scope-8.swf differ
diff --git a/test/trace/definelocal-scope-8.swf.trace b/test/trace/definelocal-scope-8.swf.trace
new file mode 100644
index 0000000..250b2b3
--- /dev/null
+++ b/test/trace/definelocal-scope-8.swf.trace
@@ -0,0 +1,8 @@
+0
+0
+0
+4
+0
+0
+0
+0
diff --git a/test/trace/definelocal-scope.as b/test/trace/definelocal-scope.as
new file mode 100644
index 0000000..eb3339f
--- /dev/null
+++ b/test/trace/definelocal-scope.as
@@ -0,0 +1,37 @@
+// makeswf -v 7 -s 200x150 -r 15 -o test-8.swf test-8.as
+
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+var y1 = 0;
+var y2 = 0;
+var y3 = 0;
+var y4 = 0;
+var a = { x1: 1, x2: 1, x3: 1, y1: 1, y2: 1, y3: 1 };
+with (a) {
+ var b = { x1: 2, x2: 2, y1: 2, y2: 2 };
+ with (b) {
+ var c = { x1: 3, y1: 3 };
+ with (c) {
+ var x1 = 4;
+ var x2 = 4;
+ var x3 = 4;
+ var x4 = 4;
+ var y1;
+ var y2;
+ var y3;
+ var y4;
+ }
+ }
+}
+trace (x1);
+trace (x2);
+trace (x3);
+trace (x4);
+trace (y1);
+trace (y2);
+trace (y3);
+trace (y4);
+
+getURL ("FSCommand:quit", "");
commit 577df517e0452b8ce81a15af27bd8522f9054542
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 25 15:59:28 2008 +0300
Fixes to DefineLocal and DefineLocal2
Make them check scope for existing variable with same name
Make DefineLocal2 not overwrite existing values
diff --git a/swfdec/swfdec_as_context.c b/swfdec/swfdec_as_context.c
index 6c679de..397ebb7 100644
--- a/swfdec/swfdec_as_context.c
+++ b/swfdec/swfdec_as_context.c
@@ -1097,7 +1097,7 @@ swfdec_as_context_eval_set_property (SwfdecAsContext *cx,
SWFDEC_ERROR ("no frame in eval_set?");
return;
}
- swfdec_as_frame_set_variable (cx->frame, name, ret);
+ swfdec_as_frame_set_variable (cx->frame, name, ret, TRUE, FALSE);
} else {
swfdec_as_object_set_variable (obj, name, ret);
}
diff --git a/swfdec/swfdec_as_frame.c b/swfdec/swfdec_as_frame.c
index d4bf392..52e311c 100644
--- a/swfdec/swfdec_as_frame.c
+++ b/swfdec/swfdec_as_frame.c
@@ -581,7 +581,7 @@ swfdec_as_frame_get_variable_and_flags (SwfdecAsFrame *frame, const char *variab
void
swfdec_as_frame_set_variable_and_flags (SwfdecAsFrame *frame, const char *variable,
- const SwfdecAsValue *value, guint default_flags)
+ const SwfdecAsValue *value, guint default_flags, gboolean overwrite, gboolean local)
{
SwfdecAsObject *pobject, *set;
GSList *walk;
@@ -593,12 +593,24 @@ swfdec_as_frame_set_variable_and_flags (SwfdecAsFrame *frame, const char *variab
for (walk = frame->scope_chain; walk; walk = walk->next) {
if (swfdec_as_object_get_variable_and_flags (walk->data, variable, NULL, NULL, &pobject) &&
pobject == walk->data) {
+ if (!overwrite)
+ return;
set = walk->data;
break;
}
}
- if (set == NULL)
- set = frame->target;
+ if (set == NULL) {
+ if (local && frame->is_local) {
+ set = SWFDEC_AS_OBJECT (frame);
+ } else {
+ set = frame->target;
+ }
+ }
+
+ if (!overwrite) {
+ if (swfdec_as_object_get_variable (set, variable, NULL))
+ return;
+ }
swfdec_as_object_set_variable_and_flags (set, variable, value, default_flags);
}
diff --git a/swfdec/swfdec_as_frame_internal.h b/swfdec/swfdec_as_frame_internal.h
index 0dc9a5e..712c3e6 100644
--- a/swfdec/swfdec_as_frame_internal.h
+++ b/swfdec/swfdec_as_frame_internal.h
@@ -79,13 +79,15 @@ SwfdecAsObject *swfdec_as_frame_get_variable_and_flags
SwfdecAsValue * value,
guint * flags,
SwfdecAsObject ** pobject);
-#define swfdec_as_frame_set_variable(frame, variable, value) \
- swfdec_as_frame_set_variable_and_flags (frame, variable, value, 0)
+#define swfdec_as_frame_set_variable(frame, variable, value, overwrite, local) \
+ swfdec_as_frame_set_variable_and_flags (frame, variable, value, 0, overwrite, local)
void swfdec_as_frame_set_variable_and_flags
(SwfdecAsFrame * frame,
const char * variable,
const SwfdecAsValue * value,
- guint default_flags);
+ guint default_flags,
+ gboolean overwrite,
+ gboolean local);
SwfdecAsDeleteReturn
swfdec_as_frame_delete_variable (SwfdecAsFrame * frame,
const char * variable);
diff --git a/swfdec/swfdec_as_interpret.c b/swfdec/swfdec_as_interpret.c
index aa43941..de86447 100644
--- a/swfdec/swfdec_as_interpret.c
+++ b/swfdec/swfdec_as_interpret.c
@@ -656,7 +656,8 @@ swfdec_action_set_variable (SwfdecAsContext *cx, guint action, const guint8 *dat
rest = s;
else
rest = swfdec_as_context_get_string (cx, rest);
- swfdec_as_frame_set_variable (cx->frame, rest, swfdec_as_stack_peek (cx, 1));
+ swfdec_as_frame_set_variable (cx->frame, rest,
+ swfdec_as_stack_peek (cx, 1), TRUE, FALSE);
}
}
swfdec_as_stack_pop_n (cx, 2);
@@ -1993,17 +1994,11 @@ swfdec_action_target_path (SwfdecAsContext *cx, guint action, const guint8 *data
static void
swfdec_action_define_local (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
- SwfdecAsObject *target;
const char *name;
name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 2));
- if (cx->frame->is_local) {
- target = SWFDEC_AS_OBJECT (cx->frame);
- } else {
- target = cx->frame->target;
- }
- swfdec_as_object_set_variable (target, name,
- swfdec_as_stack_peek (cx, 1));
+ swfdec_as_frame_set_variable (cx->frame, name, swfdec_as_stack_peek (cx, 1),
+ TRUE, TRUE);
swfdec_as_stack_pop_n (cx, 2);
}
@@ -2011,16 +2006,10 @@ static void
swfdec_action_define_local2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
{
SwfdecAsValue val = { 0, };
- SwfdecAsObject *target;
const char *name;
name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));
- if (cx->frame->is_local) {
- target = SWFDEC_AS_OBJECT (cx->frame);
- } else {
- target = cx->frame->target;
- }
- swfdec_as_object_set_variable (target, name, &val);
+ swfdec_as_frame_set_variable (cx->frame, name, &val, FALSE, TRUE);
swfdec_as_stack_pop (cx);
}
commit 5094e894f4c45421d3d8036e9d970c3804debb52
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 25 15:58:41 2008 +0300
Add a test for whether DefineLocal and DefineLocal2 overwrite existing values
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 1e61aa6..6eaf546 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -858,6 +858,15 @@ EXTRA_DIST = \
definelocal-function-target-7.swf.trace \
definelocal-function-target-8.swf \
definelocal-function-target-8.swf.trace \
+ definelocal-overwrite.as \
+ definelocal-overwrite-5.swf \
+ definelocal-overwrite-5.swf.trace \
+ definelocal-overwrite-6.swf \
+ definelocal-overwrite-6.swf.trace \
+ definelocal-overwrite-7.swf \
+ definelocal-overwrite-7.swf.trace \
+ definelocal-overwrite-8.swf \
+ definelocal-overwrite-8.swf.trace \
definelocal-target.as \
definelocal-target-5.swf \
definelocal-target-5.swf.trace \
diff --git a/test/trace/definelocal-overwrite-5.swf b/test/trace/definelocal-overwrite-5.swf
new file mode 100644
index 0000000..c3b3d85
Binary files /dev/null and b/test/trace/definelocal-overwrite-5.swf differ
diff --git a/test/trace/definelocal-overwrite-5.swf.trace b/test/trace/definelocal-overwrite-5.swf.trace
new file mode 100644
index 0000000..bb5ee5c
--- /dev/null
+++ b/test/trace/definelocal-overwrite-5.swf.trace
@@ -0,0 +1,3 @@
+0
+0
+1
diff --git a/test/trace/definelocal-overwrite-6.swf b/test/trace/definelocal-overwrite-6.swf
new file mode 100644
index 0000000..806c72e
Binary files /dev/null and b/test/trace/definelocal-overwrite-6.swf differ
diff --git a/test/trace/definelocal-overwrite-6.swf.trace b/test/trace/definelocal-overwrite-6.swf.trace
new file mode 100644
index 0000000..bb5ee5c
--- /dev/null
+++ b/test/trace/definelocal-overwrite-6.swf.trace
@@ -0,0 +1,3 @@
+0
+0
+1
diff --git a/test/trace/definelocal-overwrite-7.swf b/test/trace/definelocal-overwrite-7.swf
new file mode 100644
index 0000000..10f6eec
Binary files /dev/null and b/test/trace/definelocal-overwrite-7.swf differ
diff --git a/test/trace/definelocal-overwrite-7.swf.trace b/test/trace/definelocal-overwrite-7.swf.trace
new file mode 100644
index 0000000..bb5ee5c
--- /dev/null
+++ b/test/trace/definelocal-overwrite-7.swf.trace
@@ -0,0 +1,3 @@
+0
+0
+1
diff --git a/test/trace/definelocal-overwrite-8.swf b/test/trace/definelocal-overwrite-8.swf
new file mode 100644
index 0000000..826559c
Binary files /dev/null and b/test/trace/definelocal-overwrite-8.swf differ
diff --git a/test/trace/definelocal-overwrite-8.swf.trace b/test/trace/definelocal-overwrite-8.swf.trace
new file mode 100644
index 0000000..bb5ee5c
--- /dev/null
+++ b/test/trace/definelocal-overwrite-8.swf.trace
@@ -0,0 +1,3 @@
+0
+0
+1
diff --git a/test/trace/definelocal-overwrite.as b/test/trace/definelocal-overwrite.as
new file mode 100644
index 0000000..54eec3b
--- /dev/null
+++ b/test/trace/definelocal-overwrite.as
@@ -0,0 +1,10 @@
+// makeswf -v 7 -s 200x150 -r 15 -o test-8.swf test-8.as
+
+var x = 0;
+trace (x);
+var x;
+trace (x);
+var x = 1;
+trace (x);
+
+getURL ("FSCommand:quit", "");
commit 363b1a376bedc8cf68702fd40137f611aa067441
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 25 14:46:44 2008 +0300
Add a test for the recent block popping fix
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 78409c6..1e61aa6 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -3349,6 +3349,15 @@ EXTRA_DIST = \
tointeger-various-6.swf.trace \
tointeger-various-7.swf \
tointeger-various-7.swf.trace \
+ too-many-blocks.as \
+ too-many-blocks-5.swf \
+ too-many-blocks-5.swf.trace \
+ too-many-blocks-6.swf \
+ too-many-blocks-6.swf.trace \
+ too-many-blocks-7.swf \
+ too-many-blocks-7.swf.trace \
+ too-many-blocks-8.swf \
+ too-many-blocks-8.swf.trace \
totalframes.xml \
totalframes.swf \
totalframes.swf.trace \
diff --git a/test/trace/too-many-blocks-5.swf b/test/trace/too-many-blocks-5.swf
new file mode 100644
index 0000000..23c9ce5
Binary files /dev/null and b/test/trace/too-many-blocks-5.swf differ
diff --git a/test/trace/too-many-blocks-5.swf.trace b/test/trace/too-many-blocks-5.swf.trace
new file mode 100644
index 0000000..f58d53d
--- /dev/null
+++ b/test/trace/too-many-blocks-5.swf.trace
@@ -0,0 +1,4 @@
+0
+0
+0
+4
diff --git a/test/trace/too-many-blocks-6.swf b/test/trace/too-many-blocks-6.swf
new file mode 100644
index 0000000..a66af1a
Binary files /dev/null and b/test/trace/too-many-blocks-6.swf differ
diff --git a/test/trace/too-many-blocks-6.swf.trace b/test/trace/too-many-blocks-6.swf.trace
new file mode 100644
index 0000000..f58d53d
--- /dev/null
+++ b/test/trace/too-many-blocks-6.swf.trace
@@ -0,0 +1,4 @@
+0
+0
+0
+4
diff --git a/test/trace/too-many-blocks-7.swf b/test/trace/too-many-blocks-7.swf
new file mode 100644
index 0000000..5746cc4
Binary files /dev/null and b/test/trace/too-many-blocks-7.swf differ
diff --git a/test/trace/too-many-blocks-7.swf.trace b/test/trace/too-many-blocks-7.swf.trace
new file mode 100644
index 0000000..f58d53d
--- /dev/null
+++ b/test/trace/too-many-blocks-7.swf.trace
@@ -0,0 +1,4 @@
+0
+0
+0
+4
diff --git a/test/trace/too-many-blocks-8.swf b/test/trace/too-many-blocks-8.swf
new file mode 100644
index 0000000..7b36099
Binary files /dev/null and b/test/trace/too-many-blocks-8.swf differ
diff --git a/test/trace/too-many-blocks-8.swf.trace b/test/trace/too-many-blocks-8.swf.trace
new file mode 100644
index 0000000..f58d53d
--- /dev/null
+++ b/test/trace/too-many-blocks-8.swf.trace
@@ -0,0 +1,4 @@
+0
+0
+0
+4
diff --git a/test/trace/too-many-blocks.as b/test/trace/too-many-blocks.as
new file mode 100644
index 0000000..0f6eff0
--- /dev/null
+++ b/test/trace/too-many-blocks.as
@@ -0,0 +1,25 @@
+// makeswf -v 7 -s 200x150 -r 15 -o test-8.swf test-8.as
+
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+var a = { x1: 1, x2: 1, x3: 1 };
+with (a) {
+ var b = { x1: 2, x2: 2 };
+ with (b) {
+ var c = { x1: 3 };
+ with (c) {
+ x1 = 4;
+ x2 = 4;
+ x3 = 4;
+ x4 = 4;
+ }
+ }
+}
+trace (x1);
+trace (x2);
+trace (x3);
+trace (x4);
+
+getURL ("FSCommand:quit", "");
commit e8dfffaf9a1a0c6fcf895bfad1bb581cfe818234
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date: Fri Apr 25 14:18:16 2008 +0300
Make catch block have it's own scope
diff --git a/swfdec/swfdec_as_interpret.c b/swfdec/swfdec_as_interpret.c
index 6a57185..aa43941 100644
--- a/swfdec/swfdec_as_interpret.c
+++ b/swfdec/swfdec_as_interpret.c
@@ -2550,6 +2550,8 @@ typedef struct {
guint register_number;
char * variable_name;
};
+
+ SwfdecAsObject * scope_object;
} TryData;
static void
@@ -2594,6 +2596,11 @@ swfdec_action_try_end_catch (SwfdecAsFrame *frame, gpointer data)
cx = SWFDEC_AS_OBJECT (frame)->context;
+ g_assert (frame->scope_chain->data == try_data->scope_object);
+ frame->scope_chain =
+ g_slist_delete_link (frame->scope_chain, frame->scope_chain);
+ try_data->scope_object = NULL;
+
if (swfdec_as_context_catch (cx, &val))
{
// we got an exception while in catch block:
@@ -2637,6 +2644,14 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
// we got an exception while in try block:
// set the exception variable
// add new block for catch and jump to it
+ try_data->scope_object = swfdec_as_object_new_empty (cx);
+ cx->frame->scope_chain = g_slist_prepend (cx->frame->scope_chain,
+ try_data->scope_object);
+
+ swfdec_as_frame_push_block (frame, try_data->catch_start,
+ try_data->catch_start + try_data->catch_size,
+ swfdec_action_try_end_catch, try_data);
+ frame->pc = try_data->catch_start;
if (try_data->use_register)
{
@@ -2649,35 +2664,9 @@ swfdec_action_try_end_try (SwfdecAsFrame *frame, gpointer data)
}
else
{
- // FIXME: this is duplicate of SetVariable
- SwfdecAsObject *object;
- const char *s, *rest;
-
- s = swfdec_as_context_get_string (cx, try_data->variable_name);
- if (swfdec_action_get_movie_by_path (cx, s, &object, &rest)) {
- if (object && rest) {
- swfdec_as_object_set_variable (object,
- swfdec_as_context_get_string (cx, rest), &val);
- } else {
- if (object) {
- rest = s;
- } else {
- rest = swfdec_as_context_get_string (cx, rest);
- }
- swfdec_as_frame_set_variable (frame, rest, &val);
- }
- }
- else
- {
- SWFDEC_ERROR ("cannot set Error to variable %s",
- try_data->variable_name);
- }
+ swfdec_as_object_set_variable (try_data->scope_object,
+ swfdec_as_context_get_string (cx, try_data->variable_name), &val);
}
-
- swfdec_as_frame_push_block (frame, try_data->catch_start,
- try_data->catch_start + try_data->catch_size,
- swfdec_action_try_end_catch, try_data);
- frame->pc = try_data->catch_start;
}
else
{
More information about the Swfdec-commits
mailing list