[Swfdec] Branch 'as' - 3 commits - libswfdec/Makefile.am
libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h
libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h
libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h
libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h
libswfdec/swfdec_script.c libswfdec/swfdec_script.h
Benjamin Otte
company at kemper.freedesktop.org
Wed Mar 28 15:10:42 PDT 2007
libswfdec/Makefile.am | 2
libswfdec/swfdec_as_context.c | 124 +++++++++++++++++++++++++++++++++++++++---
libswfdec/swfdec_as_context.h | 6 +-
libswfdec/swfdec_as_frame.c | 98 +++++++++++++++++++++++++++++++++
libswfdec/swfdec_as_frame.h | 64 +++++++++++++++++++++
libswfdec/swfdec_as_object.c | 30 +++++-----
libswfdec/swfdec_as_object.h | 15 ++++-
libswfdec/swfdec_as_types.c | 5 +
libswfdec/swfdec_as_types.h | 8 +-
libswfdec/swfdec_script.c | 40 ++++++++-----
libswfdec/swfdec_script.h | 1
11 files changed, 348 insertions(+), 45 deletions(-)
New commits:
diff-tree d5b0299d9f6cc23d8b3980ba8e34b1f76ae1902d (from 6d6ccd9c1477dc96ee2171d7bfe3cfceda5020e6)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Mar 29 00:10:13 2007 +0200
more hacking on the ActionScript stuff, hooking up frames
Also, includes a rename from SWFDEC_AS_IS_FOO to SWFDEC_IS_AS_FOO
diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 1670407..8bf4e50 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -17,6 +17,7 @@ js_cflags = -I$(srcdir)/js/ -I./js -DXP_
libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES = \
swfdec_as_context.c \
+ swfdec_as_frame.c \
swfdec_as_object.c \
swfdec_as_types.c \
swfdec_amf.c \
@@ -110,6 +111,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@include_HEA
noinst_HEADERS = \
swfdec_as_context.h \
+ swfdec_as_frame.h \
swfdec_as_object.h \
swfdec_as_types.h \
swfdec_amf.h \
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 8b05dc3..e9bdc80 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -23,9 +23,11 @@
#include <string.h>
#include "swfdec_as_context.h"
+#include "swfdec_as_frame.h"
#include "swfdec_as_object.h"
#include "swfdec_as_types.h"
#include "swfdec_debug.h"
+#include "swfdec_script.h"
/*** GTK_DOC ***/
@@ -67,7 +69,7 @@ swfdec_as_context_abort (SwfdecAsContext
gboolean
swfdec_as_context_use_mem (SwfdecAsContext *context, gsize len)
{
- g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), FALSE);
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
g_return_val_if_fail (len > 0, FALSE);
context->memory += len;
@@ -77,7 +79,7 @@ swfdec_as_context_use_mem (SwfdecAsConte
void
swfdec_as_context_unuse_mem (SwfdecAsContext *context, gsize len)
{
- g_return_if_fail (SWFDEC_AS_IS_CONTEXT (context));
+ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
g_return_if_fail (len > 0);
g_return_if_fail (context->memory >= len);
@@ -166,7 +168,7 @@ swfdec_as_string_mark (const char *strin
void
swfdec_as_value_mark (SwfdecAsValue *value)
{
- g_return_if_fail (SWFDEC_AS_IS_VALUE (value));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
if (SWFDEC_AS_VALUE_IS_OBJECT (value)) {
swfdec_as_object_mark (SWFDEC_AS_VALUE_GET_OBJECT (value));
@@ -187,7 +189,7 @@ swfdec_as_context_mark_roots (gpointer k
void
swfdec_as_context_gc (SwfdecAsContext *context)
{
- g_return_if_fail (SWFDEC_AS_IS_CONTEXT (context));
+ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
SWFDEC_INFO ("invoking the garbage collector");
g_hash_table_foreach (context->objects, swfdec_as_context_mark_roots, NULL);
@@ -244,7 +246,7 @@ swfdec_as_context_create_string (SwfdecA
char *new;
if (!swfdec_as_context_use_mem (context, sizeof (char) * (2 + len)))
- return SWFDEC_AS_EMPTY_STRING;
+ return SWFDEC_AS_STR_EMPTY;
new = g_slice_alloc (2 + len);
memcpy (&new[1], string, len);
@@ -261,7 +263,7 @@ swfdec_as_context_get_string (SwfdecAsCo
const char *ret;
gsize len;
- g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
g_return_val_if_fail (string != NULL, NULL);
ret = g_hash_table_lookup (context->strings, string);
@@ -277,3 +279,111 @@ swfdec_as_context_new (void)
{
return g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
}
+
+/* defines minimum and maximum versions for which we have seperate scripts */
+#define MINSCRIPTVERSION 3
+#define MAXSCRIPTVERSION 7
+#define EXTRACT_VERSION(v) MIN ((v) - MINSCRIPTVERSION, MAXSCRIPTVERSION - MINSCRIPTVERSION)
+
+typedef JSBool (* SwfdecActionExec) (JSContext *cx, guint action, const guint8 *data, guint len);
+typedef struct {
+ const char * name; /* name identifying the action */
+ char * (* print) (guint action, const guint8 *data, guint len);
+ int remove; /* values removed from stack or -1 for dynamic */
+ int add; /* values added to the stack or -1 for dynamic */
+ SwfdecActionExec exec[MAXSCRIPTVERSION - MINSCRIPTVERSION + 1];
+ /* array is for version 3, 4, 5, 6, 7+ */
+} SwfdecActionSpec;
+
+extern const SwfdecActionSpec actions[256];
+void
+swfdec_as_context_run (SwfdecAsContext *context)
+{
+ SwfdecAsFrame *frame;
+ SwfdecScript *script;
+ const SwfdecActionSpec *spec;
+ guint8 *startpc, *pc, *endpc, *nextpc;
+ guint action, len;
+ guint8 *data;
+ int version;
+
+ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+
+ /* setup data */
+ frame = context->frame;
+ if (frame == NULL)
+ return;
+ script = frame->script;
+ version = EXTRACT_VERSION (script->version);
+ startpc = script->buffer->data;
+ endpc = startpc + script->buffer->length;
+
+ while (pc != endpc) {
+ if (pc < startpc || pc >= endpc) {
+ SWFDEC_ERROR ("pc %p not in valid range [%p, %p) anymore", pc, startpc, endpc);
+ goto internal_error;
+ }
+
+ /* decode next action */
+ action = *pc;
+ spec = actions + action;
+ if (action == 0)
+ break;
+ if (action & 0x80) {
+ if (pc + 2 >= endpc) {
+ SWFDEC_ERROR ("action %u length value out of range", action);
+ goto internal_error;
+ }
+ data = pc + 3;
+ len = pc[1] | pc[2] << 8;
+ if (data + len > endpc) {
+ SWFDEC_ERROR ("action %u length %u out of range", action, len);
+ goto internal_error;
+ }
+ nextpc = pc + 3 + len;
+ } else {
+ data = NULL;
+ len = 0;
+ nextpc = pc + 1;
+ }
+ /* check action is valid */
+ if (spec->exec[version] == NULL) {
+ SWFDEC_ERROR ("cannot interpret action %u %s for version %u", action,
+ spec->name ? spec->name : "Unknown", script->version);
+ goto internal_error;
+ }
+#if 0
+ if (spec->remove > 0) {
+ //!swfdec_script_ensure_stack (cx, spec->remove)) {
+ }
+ if (spec->add > 0 &&
+ TRUE) { //fp->sp + spec->add - MAX (spec->remove, 0) > fp->spend) {
+ SWFDEC_ERROR ("FIXME: implement stack expansion, we got an overflow");
+ goto internal_error;
+ }
+#ifndef G_DISABLE_ASSERT
+ checksp = (spec->add >= 0 && spec->remove >= 0) ? fp->sp + spec->add - spec->remove : NULL;
+#endif
+#endif
+ spec->exec[version] (NULL, action, data, len);
+#if 0
+#ifndef G_DISABLE_ASSERT
+ if (checksp != NULL && checksp != fp->sp) {
+ /* check stack was handled like expected */
+ g_error ("action %s was supposed to change the stack by %d (+%d -%d), but it changed by %td",
+ spec->name, spec->add - spec->remove, spec->add, spec->remove,
+ fp->sp - checksp + spec->add - spec->remove);
+ }
+#endif
+ if (fp->pc == pc) {
+ fp->pc = pc = nextpc;
+ } else {
+ pc = fp->pc;
+ }
+#endif
+ }
+
+internal_error:
+ return;
+}
+
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 05ac561..67e7ec2 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -37,8 +37,8 @@ typedef enum {
typedef struct _SwfdecAsContextClass SwfdecAsContextClass;
#define SWFDEC_TYPE_AS_CONTEXT (swfdec_as_context_get_type())
-#define SWFDEC_AS_IS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_CONTEXT))
-#define SWFDEC_AS_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_CONTEXT))
+#define SWFDEC_IS_AS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_CONTEXT))
+#define SWFDEC_IS_AS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_CONTEXT))
#define SWFDEC_AS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_CONTEXT, SwfdecAsContext))
#define SWFDEC_AS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_CONTEXT, SwfdecAsContextClass))
#define SWFDEC_AS_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_CONTEXT, SwfdecAsContextClass))
@@ -55,6 +55,7 @@ struct _SwfdecAsContext {
/* execution state */
unsigned int version; /* currently active version */
+ SwfdecAsFrame * frame; /* topmost stack frame */
};
struct _SwfdecAsContextClass {
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
new file mode 100644
index 0000000..8ce86db
--- /dev/null
+++ b/libswfdec/swfdec_as_frame.c
@@ -0,0 +1,98 @@
+/* SwfdecAs
+ * Copyright (C) 2007 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_as_frame.h"
+#include "swfdec_as_context.h"
+#include "swfdec_debug.h"
+
+G_DEFINE_TYPE (SwfdecAsFrame, swfdec_as_frame, SWFDEC_TYPE_AS_OBJECT)
+
+static void
+swfdec_as_frame_dispose (GObject *object)
+{
+ SwfdecAsFrame *frame = SWFDEC_AS_FRAME (object);
+
+ g_slice_free1 (sizeof (SwfdecAsValue) * frame->n_registers, frame->registers);
+ swfdec_script_unref (frame->script);
+
+ G_OBJECT_CLASS (swfdec_as_frame_parent_class)->dispose (object);
+}
+
+static void
+swfdec_as_frame_mark (SwfdecAsObject *object)
+{
+ SwfdecAsFrame *frame = SWFDEC_AS_FRAME (object);
+ guint i;
+
+ swfdec_as_object_mark (SWFDEC_AS_OBJECT (frame->next));
+ swfdec_as_object_mark (frame->scope);
+ swfdec_as_object_mark (frame->var_object);
+ for (i = 0; i < frame->n_registers; i++) {
+ swfdec_as_value_mark (&frame->registers[i]);
+ }
+ SWFDEC_AS_OBJECT_CLASS (swfdec_as_frame_parent_class)->mark (object);
+}
+
+static void
+swfdec_as_frame_class_init (SwfdecAsFrameClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass);
+
+ object_class->dispose = swfdec_as_frame_dispose;
+
+ asobject_class->mark = swfdec_as_frame_mark;
+}
+
+static void
+swfdec_as_frame_init (SwfdecAsFrame *frame)
+{
+}
+
+SwfdecAsFrame *
+swfdec_as_frame_new (SwfdecAsContext *context, SwfdecAsObject *thisp, SwfdecScript *script)
+{
+ SwfdecAsValue val;
+ SwfdecAsFrame *frame;
+ gsize size;
+
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
+ g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (thisp), NULL);
+ g_return_val_if_fail (script != NULL, NULL);
+
+ size = sizeof (SwfdecAsObject) + sizeof (SwfdecAsValue) * script->n_registers;
+ if (!swfdec_as_context_use_mem (context, size))
+ return NULL;
+ frame = g_object_new (SWFDEC_TYPE_AS_FRAME, NULL);
+ swfdec_as_object_add (SWFDEC_AS_OBJECT (frame), context, size);
+ g_object_unref (frame);
+ frame->next = context->frame;
+ context->frame = frame;
+ frame->scope = thisp;
+ frame->var_object = thisp;
+ frame->registers = g_slice_alloc0 (sizeof (SwfdecAsValue) * script->n_registers);
+ SWFDEC_AS_VALUE_SET_OBJECT (&val, thisp);
+ swfdec_as_object_set (SWFDEC_AS_OBJECT (frame), SWFDEC_AS_STR_THIS, &val);
+ return frame;
+}
+
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
new file mode 100644
index 0000000..f55cc8f
--- /dev/null
+++ b/libswfdec/swfdec_as_frame.h
@@ -0,0 +1,64 @@
+/* SwfdecAs
+ * Copyright (C) 2007 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 _SWFDEC_AS_FRAME_H_
+#define _SWFDEC_AS_FRAME_H_
+
+#include <libswfdec/swfdec_as_object.h>
+#include <libswfdec/swfdec_as_types.h>
+#include <libswfdec/swfdec_script.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecAsFrameClass SwfdecAsFrameClass;
+
+#define SWFDEC_TYPE_AS_FRAME (swfdec_as_frame_get_type())
+#define SWFDEC_IS_AS_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_FRAME))
+#define SWFDEC_IS_AS_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_FRAME))
+#define SWFDEC_AS_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_FRAME, SwfdecAsFrame))
+#define SWFDEC_AS_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_FRAME, SwfdecAsFrameClass))
+#define SWFDEC_AS_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_FRAME, SwfdecAsFrameClass))
+
+struct _SwfdecAsFrame {
+ SwfdecAsObject object;
+
+ SwfdecAsFrame * next; /* next frame (FIXME: keep a list in the context instead?) */
+ SwfdecScript * script; /* script being executed */
+ SwfdecAsObject * scope; /* scope object coming after this */
+ SwfdecAsObject * var_object; /* new variables go here */
+ SwfdecAsValue * registers; /* the registers */
+ guint n_registers; /* number of allocated registers */
+ SwfdecConstantPool * constant_pool; /* constant pool currently in use */
+ //SwfdecAsStack * stack; /* variables on the stack */
+};
+
+struct _SwfdecAsFrameClass {
+ SwfdecAsObjectClass object_class;
+};
+
+GType swfdec_as_frame_get_type (void);
+
+SwfdecAsFrame * swfdec_as_frame_new (SwfdecAsContext * context,
+ SwfdecAsObject * thisp,
+ SwfdecScript * script);
+
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index c1a3bd8..79ce1cf 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -79,8 +79,10 @@ swfdec_as_object_new (SwfdecAsContext *c
{
SwfdecAsObject *object;
- g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), NULL);
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
+ if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsObject)))
+ return NULL;
object = g_object_new (SWFDEC_TYPE_AS_OBJECT, NULL);
swfdec_as_object_add (object, context, sizeof (SwfdecAsObject));
g_object_unref (object);
@@ -90,12 +92,10 @@ swfdec_as_object_new (SwfdecAsContext *c
void
swfdec_as_object_add (SwfdecAsObject *object, SwfdecAsContext *context, gsize size)
{
- g_return_if_fail (SWFDEC_AS_IS_OBJECT (object));
- g_return_if_fail (SWFDEC_AS_IS_CONTEXT (context));
+ g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
+ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
g_return_if_fail (object->properties == NULL);
- if (!swfdec_as_context_use_mem (context, size))
- return;
object->context = context;
object->size = size;
g_hash_table_insert (context->objects, object, object);
@@ -115,7 +115,7 @@ swfdec_as_object_free_property (gpointer
void
swfdec_as_object_collect (SwfdecAsObject *object)
{
- g_return_if_fail (SWFDEC_AS_IS_OBJECT (object));
+ g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
g_return_if_fail (object->properties != NULL);
g_hash_table_foreach (object->properties, swfdec_as_object_free_property, object);
@@ -128,7 +128,7 @@ swfdec_as_object_collect (SwfdecAsObject
void
swfdec_as_object_root (SwfdecAsObject *object)
{
- g_return_if_fail (SWFDEC_AS_IS_OBJECT (object));
+ g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
g_return_if_fail ((object->flags & SWFDEC_AS_GC_ROOT) == 0);
object->flags |= SWFDEC_AS_GC_ROOT;
@@ -137,7 +137,7 @@ swfdec_as_object_root (SwfdecAsObject *o
void
swfdec_as_object_unroot (SwfdecAsObject *object)
{
- g_return_if_fail (SWFDEC_AS_IS_OBJECT (object));
+ g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
g_return_if_fail ((object->flags & SWFDEC_AS_GC_ROOT) != 0);
object->flags &= ~SWFDEC_AS_GC_ROOT;
@@ -150,9 +150,9 @@ swfdec_as_object_set_variable (SwfdecAsO
const char *s;
SwfdecAsObjectVariable *var;
- g_return_if_fail (SWFDEC_AS_IS_OBJECT (object));
- g_return_if_fail (SWFDEC_AS_IS_VALUE (variable));
- g_return_if_fail (SWFDEC_AS_IS_VALUE (value));
+ g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (variable));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
s = swfdec_as_value_to_string (object->context, variable);
var = g_hash_table_lookup (object->properties, s);
@@ -177,8 +177,8 @@ swfdec_as_object_get_variable (SwfdecAsO
SwfdecAsObjectVariable *var;
guint i;
- g_return_if_fail (SWFDEC_AS_IS_OBJECT (object));
- g_return_if_fail (SWFDEC_AS_IS_VALUE (variable));
+ g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (variable));
g_return_if_fail (value != NULL);
s = swfdec_as_value_to_string (object->context, variable);
@@ -206,8 +206,8 @@ swfdec_as_object_delete_variable (Swfdec
SwfdecAsObjectVariable *var;
guint i;
- g_return_if_fail (SWFDEC_AS_IS_OBJECT (object));
- g_return_if_fail (SWFDEC_AS_IS_VALUE (variable));
+ g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
+ g_return_if_fail (SWFDEC_IS_AS_VALUE (variable));
s = swfdec_as_value_to_string (object->context, variable);
for (i = 0; i < 256 && object != NULL; i++) {
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 581d0f2..0accee4 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -34,8 +34,8 @@ typedef enum {
typedef struct _SwfdecAsObjectClass SwfdecAsObjectClass;
#define SWFDEC_TYPE_AS_OBJECT (swfdec_as_object_get_type())
-#define SWFDEC_AS_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_OBJECT))
-#define SWFDEC_AS_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_OBJECT))
+#define SWFDEC_IS_AS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_OBJECT))
+#define SWFDEC_IS_AS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_OBJECT))
#define SWFDEC_AS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObject))
#define SWFDEC_AS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObjectClass))
#define SWFDEC_AS_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_OBJECT, SwfdecAsObjectClass))
@@ -77,6 +77,17 @@ void swfdec_as_object_get_variable (Swf
SwfdecAsValue * value);
void swfdec_as_object_delete_variable(SwfdecAsObject * object,
const SwfdecAsValue * variable);
+/* shortcuts, you probably don't want to bind them */
+#define swfdec_as_object_set(object, name, value) G_STMT_START { \
+ SwfdecAsValue __variable; \
+ SWFDEC_AS_VALUE_SET_STRING (&__variable, (name)); \
+ swfdec_as_object_set_variable ((object), &__variable, (value)); \
+}G_STMT_END
+#define swfdec_as_object_get(object, name, value) G_STMT_START { \
+ SwfdecAsValue __variable; \
+ SWFDEC_AS_VALUE_SET_STRING (&__variable, (name)); \
+ swfdec_as_object_get_variable ((object), &__variable, (value)); \
+}G_STMT_END
G_END_DECLS
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index bc932e9..2b84330 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -30,6 +30,7 @@
const char *swfdec_as_strings[] = {
SWFDEC_AS_CONSTANT_STRING (""),
SWFDEC_AS_CONSTANT_STRING ("__proto__"),
+ SWFDEC_AS_CONSTANT_STRING ("this"),
/* add more here */
NULL
};
@@ -37,8 +38,8 @@ const char *swfdec_as_strings[] = {
const char *
swfdec_as_value_to_string (SwfdecAsContext *context, const SwfdecAsValue *value)
{
- g_return_val_if_fail (SWFDEC_AS_IS_CONTEXT (context), SWFDEC_AS_EMPTY_STRING);
- g_return_val_if_fail (SWFDEC_AS_IS_VALUE (value), SWFDEC_AS_EMPTY_STRING);
+ g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), SWFDEC_AS_STR_EMPTY);
+ g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), SWFDEC_AS_STR_EMPTY);
if (SWFDEC_AS_VALUE_IS_STRING (value)) {
return SWFDEC_AS_VALUE_GET_STRING (value);
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index f171341..6fe9fbc 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
typedef guint8 SwfdecAsType;
typedef struct _SwfdecAsContext SwfdecAsContext;
+typedef struct _SwfdecAsFrame SwfdecAsFrame;
typedef struct _SwfdecAsObject SwfdecAsObject;
typedef struct _SwfdecAsValue SwfdecAsValue;
@@ -48,7 +49,7 @@ struct _SwfdecAsValue {
} value;
};
-#define SWFDEC_AS_IS_VALUE(val) ((val)->type <= SWFDEC_TYPE_AS_OBJECT)
+#define SWFDEC_IS_AS_VALUE(val) ((val)->type <= SWFDEC_TYPE_AS_OBJECT)
#define SWFDEC_AS_VALUE_IS_UNDEFINED(val) ((val)->type == SWFDEC_TYPE_AS_UNDEFINED)
#define SWFDEC_AS_VALUE_SET_UNDEFINED(val) (val)->type = SWFDEC_TYPE_AS_UNDEFINED
@@ -87,8 +88,9 @@ struct _SwfdecAsValue {
/* List of static strings that are required all the time */
extern const char *swfdec_as_strings[];
-#define SWFDEC_AS_EMPTY_STRING (swfdec_as_strings[0] + 1)
-#define SWFDEC_AS_PROTO_STRING (swfdec_as_strings[1] + 1)
+#define SWFDEC_AS_STR_EMPTY (swfdec_as_strings[0] + 1)
+#define SWFDEC_AS_STR_PROTO (swfdec_as_strings[1] + 1)
+#define SWFDEC_AS_STR_THIS (swfdec_as_strings[2] + 1)
const char * swfdec_as_value_to_string (SwfdecAsContext * context,
diff-tree 6d6ccd9c1477dc96ee2171d7bfe3cfceda5020e6 (from 97c15c36effab2617b4f5157374f7612b7e8379e)
Author: Benjamin Otte <otte at gnome.org>
Date: Thu Mar 29 00:08:33 2007 +0200
let scripts handle their number of registers
Also, implement swfdec_constant_pool_attach_to_context, which puts
all strings of a context into a context
diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index a9f16e0..6b7477e 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -22,6 +22,7 @@
#endif
#include "swfdec_script.h"
+#include "swfdec_as_context.h"
#include "swfdec_debug.h"
#include "swfdec_debugger.h"
#include "swfdec_scriptable.h"
@@ -82,6 +83,20 @@ swfdec_constant_pool_new_from_action (co
return pool;
}
+void
+swfdec_constant_pool_attach_to_context (SwfdecConstantPool *pool, SwfdecAsContext *context)
+{
+ guint i;
+
+ g_return_if_fail (pool != NULL);
+ g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+
+ for (i = 0; i < pool->len; i++) {
+ g_ptr_array_index (pool, i) = (gpointer) swfdec_as_context_get_string (context,
+ g_ptr_array_index (pool, i));
+ }
+}
+
guint
swfdec_constant_pool_size (SwfdecConstantPool *pool)
{
@@ -174,14 +189,8 @@ swfdec_script_ensure_stack (JSContext *c
return JS_TRUE;
}
-static gboolean
-swfdec_action_has_register (JSContext *cx, guint i)
-{
- if (cx->fp->fun == NULL)
- return i < 4;
- else
- return i < cx->fp->fun->nvars;
-}
+#define swfdec_action_has_register(cx, i) \
+ ((i) < ((SwfdecScript *) (cx)->fp->swf)->n_registers)
static SwfdecMovie *
swfdec_action_get_target (JSContext *cx)
@@ -1707,20 +1716,21 @@ swfdec_action_define_function (JSContext
if (fun == NULL)
return JS_FALSE;
if (v2) {
- fun->nvars = swfdec_bits_get_u8 (&bits) + 1;
+ script->n_registers = swfdec_bits_get_u8 (&bits) + 1;
flags = swfdec_bits_get_u16 (&bits);
preloads = g_new0 (guint8, n_args);
} else {
- fun->nvars = 5;
+ script->n_registers = 5;
}
+ fun->nvars = script->n_registers;
for (i = 0; i < n_args; i++) {
JSAtom *atom;
const char *arg_name;
if (v2) {
guint preload = swfdec_bits_get_u8 (&bits);
- if (preload && preload >= fun->nvars) {
+ if (preload && preload >= script->n_registers) {
SWFDEC_ERROR ("argument %u is preloaded into register %u out of %u",
- i, preload, fun->nvars);
+ i, preload, script->n_registers);
return JS_FALSE;
}
if (preload != 0) {
@@ -2489,7 +2499,7 @@ typedef struct {
/* array is for version 3, 4, 5, 6, 7+ */
} SwfdecActionSpec;
-static const SwfdecActionSpec actions[256] = {
+const SwfdecActionSpec actions[256] = {
/* version 3 */
[0x04] = { "NextFrame", NULL, 0, 0, { swfdec_action_next_frame, swfdec_action_next_frame, swfdec_action_next_frame, swfdec_action_next_frame, swfdec_action_next_frame } },
[0x05] = { "PreviousFrame", NULL, 0, 0, { swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame, swfdec_action_previous_frame } },
@@ -2731,6 +2741,8 @@ swfdec_script_new (SwfdecBits *bits, con
script->refcount = 1;
script->name = g_strdup (name ? name : "Unnamed script");
script->version = version;
+ /* by default, a function has 4 registers */
+ script->n_registers = 5;
/* These flags are the default arguments used by scripts read from a file.
* DefineFunction and friends override this */
script->flags = SWFDEC_SCRIPT_SUPPRESS_ARGS;
@@ -3102,7 +3114,7 @@ swfdec_script_execute (SwfdecScript *scr
frame.scopeChain = obj;
frame.varobj = obj;
/* allocate stack for variables */
- frame.nvars = 4;
+ frame.nvars = script->n_registers;
frame.vars = js_AllocRawStack (cx, frame.nvars, &mark);
if (frame.vars == NULL) {
return JS_FALSE;
diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h
index d55cdbc..b8fdcbb 100644
--- a/libswfdec/swfdec_script.h
+++ b/libswfdec/swfdec_script.h
@@ -53,6 +53,7 @@ struct _SwfdecScript {
unsigned int refcount; /* reference count */
char * name; /* name identifying this script */
unsigned int version; /* version of the script */
+ unsigned int n_registers; /* number of registers */
gpointer debugger; /* debugger owning us or NULL */
/* needed by functions */
SwfdecBuffer * constant_pool; /* constant pool action */
diff-tree 97c15c36effab2617b4f5157374f7612b7e8379e (from d906de1000e1ad4859df4b84c6b67129e70b3ac2)
Author: Benjamin Otte <otte at gnome.org>
Date: Wed Mar 28 16:45:19 2007 +0200
export swfdec_object_mark
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 84f617f..8b05dc3 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -142,7 +142,7 @@ swfdec_as_context_collect (SwfdecAsConte
g_print (">> done collecting garbage\n");
}
-static inline void
+void
swfdec_as_object_mark (SwfdecAsObject *object)
{
SwfdecAsObjectClass *klass;
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 3dde6c1..05ac561 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -76,6 +76,7 @@ gboolean swfdec_as_context_use_mem
gsize len);
void swfdec_as_context_unuse_mem (SwfdecAsContext * context,
gsize len);
+void swfdec_as_object_mark (SwfdecAsObject * object);
void swfdec_as_value_mark (SwfdecAsValue * value);
void swfdec_as_string_mark (const char * string);
void swfdec_as_context_gc (SwfdecAsContext * context);
More information about the Swfdec
mailing list