[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