[Swfdec] 11 commits - libswfdec/swfdec_font.c libswfdec/swfdec_font.h libswfdec/swfdec_js_movie.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h test/.gitignore test/trace

Benjamin Otte company at kemper.freedesktop.org
Fri Feb 16 13:03:03 PST 2007


 libswfdec/swfdec_font.c      |    4 
 libswfdec/swfdec_font.h      |    2 
 libswfdec/swfdec_js_movie.c  |    8 -
 libswfdec/swfdec_script.c    |  225 +++++++++++++++++++++++++++++++++++++++----
 libswfdec/swfdec_script.h    |   14 ++
 test/.gitignore              |    1 
 test/trace/Makefile.am       |    6 +
 test/trace/height4.swf       |binary
 test/trace/height4.swf.trace |    5 
 test/trace/scope.swf         |binary
 test/trace/scope.swf.trace   |    2 
 test/trace/scope2.swf        |binary
 test/trace/scope2.swf.trace  |    2 
 13 files changed, 244 insertions(+), 25 deletions(-)

New commits:
diff-tree d33393b8767f81772dee644af8bc7143e766e4bb (from 4f71cc6f5f14bcc3c69cff4c0c9dca27b7f476fe)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 21:12:39 2007 +0100

    add 2 tests for function scopes

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index d5706dc..f1755ee 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -90,6 +90,10 @@ EXTRA_DIST = \
 	order.swf.trace \
 	rotation-5.swf \
 	rotation-5.swf.trace \
+	scope.swf \
+	scope.swf.trace \
+	scope2.swf \
+	scope2.swf.trace \
 	setvariable.swf \
 	setvariable.swf.trace \
 	transform.swf \
diff --git a/test/trace/scope.swf b/test/trace/scope.swf
new file mode 100755
index 0000000..b7a9a90
Binary files /dev/null and b/test/trace/scope.swf differ
diff --git a/test/trace/scope.swf.trace b/test/trace/scope.swf.trace
new file mode 100755
index 0000000..fd3c81a
--- /dev/null
+++ b/test/trace/scope.swf.trace
@@ -0,0 +1,2 @@
+5
+5
diff --git a/test/trace/scope2.swf b/test/trace/scope2.swf
new file mode 100755
index 0000000..78d454c
Binary files /dev/null and b/test/trace/scope2.swf differ
diff --git a/test/trace/scope2.swf.trace b/test/trace/scope2.swf.trace
new file mode 100755
index 0000000..fd3c81a
--- /dev/null
+++ b/test/trace/scope2.swf.trace
@@ -0,0 +1,2 @@
+5
+5
diff-tree 4f71cc6f5f14bcc3c69cff4c0c9dca27b7f476fe (from aabc4fdacdad8392d185467be20a858d2bff1cad)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 21:11:56 2007 +0100

    use this as parent in DefineFunction

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 95a5561..9a9dd75 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1439,10 +1439,10 @@ swfdec_action_do_define_function (JSCont
   n_args = swfdec_bits_get_u16 (&bits);
   if (*function_name == '\0') {
     /* anonymous function */
-    fun = JS_NewFunction (cx, NULL, n_args, JSFUN_LAMBDA, NULL, NULL);
+    fun = JS_NewFunction (cx, NULL, n_args, JSFUN_LAMBDA, cx->fp->thisp, NULL);
   } else {
     /* named function */
-    fun = JS_NewFunction (cx, NULL, n_args, 0, NULL, function_name);
+    fun = JS_NewFunction (cx, NULL, n_args, 0, cx->fp->thisp, function_name);
   }
   if (fun == NULL)
     return JS_FALSE;
diff-tree aabc4fdacdad8392d185467be20a858d2bff1cad (from debdc90a5da93480aa82e2d78331720c4f53c103)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 19:23:42 2007 +0100

    make DefineFunction2 work
    
    various changes, including:
    - make DefineFunction2 really work (it used to not work before)
    - allocate 4 local variables in swfdec_script_interpret

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index dc8b2a5..95a5561 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1418,7 +1418,8 @@ swfdec_action_init_object (JSContext *cx
 }
 
 static JSBool
-swfdec_action_define_function (JSContext *cx, guint action, const guint8 *data, guint len)
+swfdec_action_do_define_function (JSContext *cx, guint action,
+    const guint8 *data, guint len, gboolean v2)
 {
   const char *function_name;
   guint i, n_args, size;
@@ -1426,7 +1427,8 @@ swfdec_action_define_function (JSContext
   JSFunction *fun;
   SwfdecScript *script;
   gboolean has_preloads = FALSE;
-  gboolean v2 = (action == 0x8e);
+  guint flags = 0;
+  guint8 *preloads = NULL;
 
   swfdec_bits_init_data (&bits, data, len);
   function_name = swfdec_bits_get_string (&bits);
@@ -1446,8 +1448,8 @@ swfdec_action_define_function (JSContext
     return JS_FALSE;
   if (v2) {
     fun->nvars = swfdec_bits_get_u8 (&bits);
-    script->flags = swfdec_bits_get_u16 (&bits);
-    script->preloads = g_new0 (guint8, n_args);
+    flags = swfdec_bits_get_u16 (&bits);
+    preloads = g_new0 (guint8, n_args);
   } else {
     fun->nvars = 4;
   }
@@ -1462,9 +1464,10 @@ swfdec_action_define_function (JSContext
 	return JS_FALSE;
       }
       if (preload != 0) {
-	script->preloads[i] = preload;
+	preloads[i] = preload;
 	swfdec_bits_skip_string (&bits);
 	has_preloads = TRUE;
+	continue;
       }
     }
     arg_name = swfdec_bits_skip_string (&bits);
@@ -1483,9 +1486,9 @@ swfdec_action_define_function (JSContext
       return JS_FALSE;
     }
   }
-  if (script->preloads && !has_preloads) {
-    g_free (script->preloads);
-    script->preloads = NULL;
+  if (preloads && !has_preloads) {
+    g_free (preloads);
+    preloads = NULL;
   }
   size = swfdec_bits_get_u16 (&bits);
   /* check the script can be created */
@@ -1509,8 +1512,11 @@ swfdec_action_define_function (JSContext
   }
   if (script == NULL) {
     SWFDEC_ERROR ("failed to create script");
+    g_free (preloads);
     return JS_FALSE;
   }
+  script->flags = flags;
+  script->preloads = preloads;
   fun->swf = script;
   /* attach the function */
   if (*function_name == '\0') {
@@ -1531,6 +1537,18 @@ swfdec_action_define_function (JSContext
 }
 
 static JSBool
+swfdec_action_define_function (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  return swfdec_action_do_define_function (cx, action, data, len, FALSE);
+}
+
+static JSBool
+swfdec_action_define_function2 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  return swfdec_action_do_define_function (cx, action, data, len, TRUE);
+}
+
+static JSBool
 swfdec_action_bitwise (JSContext *cx, guint action, const guint8 *data, guint len)
 {
   guint32 a, b;
@@ -2109,7 +2127,7 @@ static const SwfdecActionSpec actions[25
   /* version 4 */
   [0x8d] = { "WaitForFrame2", swfdec_action_print_wait_for_frame2, 1, 0, { NULL, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2 } },
   /* version 7 */
-  [0x8e] = { "DefineFunction2", swfdec_action_print_define_function, 0, -1, { NULL, NULL, NULL, NULL, swfdec_action_define_function } },
+  [0x8e] = { "DefineFunction2", swfdec_action_print_define_function, 0, -1, { NULL, NULL, NULL, NULL, swfdec_action_define_function2 } },
   [0x8f] = { "Try", NULL },
   /* version 5 */
   [0x94] = { "With", NULL },
@@ -2517,6 +2535,7 @@ swfdec_script_execute (SwfdecScript *scr
   JSStackFrame *oldfp, frame;
   JSObject *obj;
   JSBool ok;
+  void *mark;
 
   g_return_val_if_fail (script != NULL, JSVAL_VOID);
   g_return_val_if_fail (SWFDEC_IS_SCRIPTABLE (scriptable), JSVAL_VOID);
@@ -2534,8 +2553,8 @@ swfdec_script_execute (SwfdecScript *scr
   frame.swf = script;
   frame.constant_pool = NULL;
   frame.thisp = obj;
-  frame.argc = frame.nvars = 0;
-  frame.argv = frame.vars = NULL;
+  frame.argc = 0;
+  frame.argv = NULL;
   frame.annotation = NULL;
   frame.sharpArray = NULL;
   frame.rval = JSVAL_VOID;
@@ -2549,6 +2568,14 @@ swfdec_script_execute (SwfdecScript *scr
   frame.dormantNext = NULL;
   frame.objAtomMap = NULL;
 
+  /* allocate stack for variables */
+  frame.nvars = 4;
+  frame.vars = js_AllocStack (cx, frame.nvars, &mark);
+  if (frame.vars == NULL) {
+    return JS_FALSE;
+  }
+  frame.vars[0] = frame.vars[1] = frame.vars[2] = frame.vars[3] = JSVAL_VOID;
+
   if (oldfp) {
     g_assert (!oldfp->dormantNext);
     oldfp->dormantNext = cx->dormantFrameChain;
@@ -2563,7 +2590,7 @@ swfdec_script_execute (SwfdecScript *scr
    */
   ok = swfdec_script_interpret (script, cx, &frame.rval);
 
-  /* FIXME: where to clean this up? */
+  js_FreeStack (cx, mark);
   if (frame.constant_pool)
     swfdec_constant_pool_free (frame.constant_pool);
 
diff-tree debdc90a5da93480aa82e2d78331720c4f53c103 (from 1abcc041eb03537f5f95ff42e3feada49b90d5a4)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 15:54:28 2007 +0100

    implement ActionModulo

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 8859440..dc8b2a5 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -28,8 +28,9 @@
 #include "js/jscntxt.h"
 #include "js/jsinterp.h"
 
-#include <string.h>
+#include <errno.h>
 #include <math.h>
+#include <string.h>
 #include "swfdec_decoder.h"
 #include "swfdec_js.h"
 #include "swfdec_movie.h"
@@ -1691,6 +1692,43 @@ swfdec_action_store_register (JSContext 
   return JS_TRUE;
 }
 
+static JSBool
+swfdec_action_modulo_5 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  double x, y;
+
+  x = swfdec_action_to_number (cx, cx->fp->sp[-1]);
+  y = swfdec_action_to_number (cx, cx->fp->sp[-2]);
+  cx->fp->sp--;
+  errno = 0;
+  x = fmod (x, y);
+  if (errno != 0) {
+    cx->fp->sp[-1] = DOUBLE_TO_JSVAL (cx->runtime->jsNaN);
+    return JS_TRUE;
+  } else {
+    return JS_NewNumberValue (cx, x, &cx->fp->sp[-1]);
+  }
+}
+
+static JSBool
+swfdec_action_modulo_7 (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  double x, y;
+
+  if (!swfdec_value_to_number_7 (cx, cx->fp->sp[-1], &x) ||
+      !swfdec_value_to_number_7 (cx, cx->fp->sp[-2], &y))
+    return JS_FALSE;
+  cx->fp->sp--;
+  errno = 0;
+  x = fmod (x, y);
+  if (errno != 0) {
+    cx->fp->sp[-1] = DOUBLE_TO_JSVAL (cx->runtime->jsNaN);
+    return JS_TRUE;
+  } else {
+    return JS_NewNumberValue (cx, x, &cx->fp->sp[-1]);
+  }
+}
+
 /*** PRINT FUNCTIONS ***/
 
 static char *
@@ -2020,7 +2058,7 @@ static const SwfdecActionSpec actions[25
   [0x3c] = { "DefineLocal", NULL, 2, 0, { NULL, NULL, swfdec_action_define_local, swfdec_action_define_local, swfdec_action_define_local } },
   [0x3d] = { "CallFunction", NULL, -1, 1, { NULL, NULL, swfdec_action_call_function, swfdec_action_call_function, swfdec_action_call_function } },
   [0x3e] = { "Return", NULL, 1, 0, { NULL, NULL, swfdec_action_return, swfdec_action_return, swfdec_action_return } },
-  [0x3f] = { "Modulo", NULL },
+  [0x3f] = { "Modulo", NULL, 2, 1, { NULL, NULL, swfdec_action_modulo_5, swfdec_action_modulo_5, swfdec_action_modulo_7 } },
   [0x40] = { "NewObject", NULL, -1, 1, { NULL, NULL, swfdec_action_new_object, swfdec_action_new_object, swfdec_action_new_object } },
   [0x41] = { "DefineLocal2", NULL, 1, 0, { NULL, NULL, swfdec_action_define_local2, swfdec_action_define_local2, swfdec_action_define_local2 } },
   [0x42] = { "InitArray", NULL },
diff-tree 1abcc041eb03537f5f95ff42e3feada49b90d5a4 (from cddfdb3c4ca0782b1d9e9c97fabf64a024120762)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 10:04:37 2007 +0100

    implement StoreRegister and pushing registers in ActionPush

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 54913b2..8859440 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -124,6 +124,15 @@ swfdec_constant_pool_get_area (SwfdecScr
 
 /*** SUPPORT FUNCTIONS ***/
 
+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;
+}
+
 static SwfdecMovie *
 swfdec_action_get_target (JSContext *cx)
 {
@@ -461,6 +470,16 @@ swfdec_action_push (JSContext *cx, guint
       case 3: /* undefined */
 	*cx->fp->sp++ = JSVAL_VOID;
 	break;
+      case 4: /* register */
+	{
+	  guint regnum = swfdec_bits_get_u8 (&bits);
+	  if (!swfdec_action_has_register (cx, regnum)) {
+	    SWFDEC_ERROR ("cannot Push register %u: not enough registers", regnum);
+	    return JS_FALSE;
+	  }
+	  *cx->fp->sp++ = cx->fp->vars[regnum];
+	  break;
+	}
       case 5: /* boolean */
 	*cx->fp->sp++ = swfdec_bits_get_u8 (&bits) ? JSVAL_TRUE : JSVAL_FALSE;
 	break;
@@ -512,7 +531,6 @@ swfdec_action_push (JSContext *cx, guint
 	    return JS_FALSE;
 	  break;
 	}
-      case 4: /* register */
       default:
 	SWFDEC_ERROR ("Push: type %u not implemented", type);
 	return JS_FALSE;
@@ -1658,9 +1676,34 @@ swfdec_action_delete (JSContext *cx, gui
   return JS_DeleteProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[0]), name);
 }
 
+static JSBool
+swfdec_action_store_register (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  if (len != 1) {
+    SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len);
+    return JS_FALSE;
+  }
+  if (!swfdec_action_has_register (cx, *data)) {
+    SWFDEC_ERROR ("Cannot store into register %u, not enough registers", (guint) *data);
+    return JS_FALSE;
+  }
+  cx->fp->vars[*data] = cx->fp->sp[-1];
+  return JS_TRUE;
+}
+
 /*** PRINT FUNCTIONS ***/
 
 static char *
+swfdec_action_print_store_register (guint action, const guint8 *data, guint len)
+{
+  if (len != 1) {
+    SWFDEC_ERROR ("StoreRegister action requires a length of 1, but got %u", len);
+    return NULL;
+  }
+  return g_strdup_printf ("StoreRegister %u", (guint) *data);
+}
+
+static char *
 swfdec_action_print_set_target (guint action, const guint8 *data, guint len)
 {
   if (!memchr (data, 0, len)) {
@@ -1795,6 +1838,9 @@ swfdec_action_print_push (guint action, 
       case 3: /* undefined */
 	g_string_append (string, "void");
 	break;
+      case 4: /* register */
+	g_string_append_printf (string, "Register %u", swfdec_bits_get_u8 (&bits));
+	break;
       case 5: /* boolean */
 	g_string_append (string, swfdec_bits_get_u8 (&bits) ? "True" : "False");
 	break;
@@ -1810,7 +1856,6 @@ swfdec_action_print_push (guint action, 
       case 9: /* 16bit ConstantPool address */
 	g_string_append_printf (string, "Pool %u", swfdec_bits_get_u16 (&bits));
 	break;
-      case 4: /* register */
       default:
 	SWFDEC_ERROR ("Push: type %u not implemented", type);
 	return JS_FALSE;
@@ -2017,7 +2062,7 @@ static const SwfdecActionSpec actions[25
   [0x81] = { "GotoFrame", swfdec_action_print_goto_frame, 0, 0, { swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame, swfdec_action_goto_frame } },
   [0x83] = { "GetURL", swfdec_action_print_get_url, 0, 0, { swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url, swfdec_action_get_url } },
   /* version 5 */
-  [0x87] = { "StoreRegister", NULL },
+  [0x87] = { "StoreRegister", swfdec_action_print_store_register, 1, 1, { NULL, NULL, swfdec_action_store_register, swfdec_action_store_register, swfdec_action_store_register } },
   [0x88] = { "ConstantPool", swfdec_action_print_constant_pool, 0, 0, { NULL, NULL, swfdec_action_constant_pool, swfdec_action_constant_pool, swfdec_action_constant_pool } },
   /* version 3 */
   [0x8a] = { "WaitForFrame", swfdec_action_print_wait_for_frame, 0, 0, { swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame, swfdec_action_wait_for_frame } },
diff-tree cddfdb3c4ca0782b1d9e9c97fabf64a024120762 (from 31af4f795a29ab40cf4584cc45a291286b059928)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 09:52:31 2007 +0100

    implement ActionDelete

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 0f279e5..54913b2 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1644,6 +1644,20 @@ swfdec_action_return (JSContext *cx, gui
   return JS_TRUE;
 }
 
+static JSBool
+swfdec_action_delete (JSContext *cx, guint action, const guint8 *data, guint len)
+{
+  const char *name;
+  
+  cx->fp->sp -= 2;
+  name = swfdec_js_to_string (cx, cx->fp->sp[1]);
+  if (name == NULL)
+    return JS_FALSE;
+  if (!JSVAL_IS_OBJECT (cx->fp->sp[0]))
+    return JS_TRUE;
+  return JS_DeleteProperty (cx, JSVAL_TO_OBJECT (cx->fp->sp[0]), name);
+}
+
 /*** PRINT FUNCTIONS ***/
 
 static char *
@@ -1956,7 +1970,7 @@ static const SwfdecActionSpec actions[25
   [0x36] = { "MBCharToAscii", NULL },
   [0x37] = { "MVAsciiToChar", NULL },
   /* version 5 */
-  [0x3a] = { "Delete", NULL },
+  [0x3a] = { "Delete", NULL, 2, 0, { NULL, NULL, swfdec_action_delete, swfdec_action_delete, swfdec_action_delete } },
   [0x3b] = { "Delete2", NULL },
   [0x3c] = { "DefineLocal", NULL, 2, 0, { NULL, NULL, swfdec_action_define_local, swfdec_action_define_local, swfdec_action_define_local } },
   [0x3d] = { "CallFunction", NULL, -1, 1, { NULL, NULL, swfdec_action_call_function, swfdec_action_call_function, swfdec_action_call_function } },
diff-tree 31af4f795a29ab40cf4584cc45a291286b059928 (from 8a164b9aeff20d0b77f2225135b688cc4d820905)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 09:46:40 2007 +0100

    implement DefineFunction2 partially

diff --git a/libswfdec/swfdec_script.c b/libswfdec/swfdec_script.c
index 14feaa1..0f279e5 100644
--- a/libswfdec/swfdec_script.c
+++ b/libswfdec/swfdec_script.c
@@ -1406,6 +1406,8 @@ swfdec_action_define_function (JSContext
   SwfdecBits bits;
   JSFunction *fun;
   SwfdecScript *script;
+  gboolean has_preloads = FALSE;
+  gboolean v2 = (action == 0x8e);
 
   swfdec_bits_init_data (&bits, data, len);
   function_name = swfdec_bits_get_string (&bits);
@@ -1423,9 +1425,30 @@ swfdec_action_define_function (JSContext
   }
   if (fun == NULL)
     return JS_FALSE;
+  if (v2) {
+    fun->nvars = swfdec_bits_get_u8 (&bits);
+    script->flags = swfdec_bits_get_u16 (&bits);
+    script->preloads = g_new0 (guint8, n_args);
+  } else {
+    fun->nvars = 4;
+  }
   for (i = 0; i < n_args; i++) {
     JSAtom *atom;
-    const char *arg_name = swfdec_bits_get_string (&bits);
+    const char *arg_name;
+    if (v2) {
+      guint preload = swfdec_bits_get_u8 (&bits);
+      if (preload && preload >= fun->nvars) {
+	SWFDEC_ERROR ("argument %u is preloaded into register %u out of %u", 
+	    i, preload, fun->nvars);
+	return JS_FALSE;
+      }
+      if (preload != 0) {
+	script->preloads[i] = preload;
+	swfdec_bits_skip_string (&bits);
+	has_preloads = TRUE;
+      }
+    }
+    arg_name = swfdec_bits_skip_string (&bits);
     if (arg_name == NULL || *arg_name == '\0') {
       SWFDEC_ERROR ("empty argument name not allowed");
       return JS_FALSE;
@@ -1441,6 +1464,10 @@ swfdec_action_define_function (JSContext
       return JS_FALSE;
     }
   }
+  if (script->preloads && !has_preloads) {
+    g_free (script->preloads);
+    script->preloads = NULL;
+  }
   size = swfdec_bits_get_u16 (&bits);
   /* check the script can be created */
   script = cx->fp->swf;
@@ -1635,8 +1662,9 @@ swfdec_action_print_define_function (gui
   GString *string;
   const char *function_name;
   guint i, n_args, size;
+  gboolean v2 = (action == 0x8e);
 
-  string = g_string_new ("DefineFunction ");
+  string = g_string_new (v2 ? "DefineFunction2 " : "DefineFunction ");
   swfdec_bits_init_data (&bits, data, len);
   function_name = swfdec_bits_get_string (&bits);
   if (function_name == NULL) {
@@ -1650,17 +1678,30 @@ swfdec_action_print_define_function (gui
   }
   n_args = swfdec_bits_get_u16 (&bits);
   g_string_append_c (string, '(');
+  if (v2) {
+  /* n_regs = */ swfdec_bits_get_u8 (&bits);
+  /* flags = */ swfdec_bits_get_u16 (&bits);
+  }
  
   for (i = 0; i < n_args; i++) {
-    const char *arg_name = swfdec_bits_get_string (&bits);
-    if (arg_name == NULL || *arg_name == '\0') {
+    guint preload;
+    const char *arg_name;
+    if (v2)
+      preload = swfdec_bits_get_u8 (&bits);
+    else
+      preload = 0;
+    arg_name = swfdec_bits_get_string (&bits);
+    if (preload == 0 && (arg_name == NULL || *arg_name == '\0')) {
       SWFDEC_ERROR ("empty argument name not allowed");
       g_string_free (string, TRUE);
       return NULL;
     }
     if (i)
       g_string_append (string, ", ");
-    g_string_append (string, arg_name);
+    if (preload)
+      g_string_append_printf (string, "PRELOAD %u", preload);
+    else
+      g_string_append (string, arg_name);
   }
   g_string_append_c (string, ')');
   size = swfdec_bits_get_u16 (&bits);
@@ -1971,7 +2012,7 @@ static const SwfdecActionSpec actions[25
   /* version 4 */
   [0x8d] = { "WaitForFrame2", swfdec_action_print_wait_for_frame2, 1, 0, { NULL, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2, swfdec_action_wait_for_frame2 } },
   /* version 7 */
-  [0x8e] = { "DefineFunction2", NULL },
+  [0x8e] = { "DefineFunction2", swfdec_action_print_define_function, 0, -1, { NULL, NULL, NULL, NULL, swfdec_action_define_function } },
   [0x8f] = { "Try", NULL },
   /* version 5 */
   [0x94] = { "With", NULL },
@@ -2150,6 +2191,7 @@ swfdec_script_unref (SwfdecScript *scrip
   if (script->constant_pool)
     swfdec_buffer_unref (script->constant_pool);
   g_free (script->name);
+  g_free (script->preloads);
   g_free (script);
 }
 
@@ -2187,6 +2229,29 @@ swfdec_script_interpret (SwfdecScript *s
   version = EXTRACT_VERSION (script->version);
   *rval = JSVAL_VOID;
   fp = cx->fp;
+  /* do the preloading */
+  if (script->preloads) {
+    guint i;
+    for (i = 0; i < fp->fun->nargs; i++) {
+      if (script->preloads[i])
+	fp->vars[script->preloads[i]] = fp->argv[i];
+    }
+  }
+  if (script->flags) {
+    guint preload_reg = 0;
+    SwfdecPlayer *player = JS_GetContextPrivate (cx);
+    if (script->flags & SWFDEC_SCRIPT_PRELOAD_THIS)
+      fp->vars[preload_reg++] = OBJECT_TO_JSVAL (fp->thisp);
+    if (script->flags & SWFDEC_SCRIPT_PRELOAD_ARGS)
+  
+    if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER ||
+	script->flags & SWFDEC_SCRIPT_PRELOAD_ROOT ||
+	script->flags & SWFDEC_SCRIPT_PRELOAD_PARENT) {
+      g_assert_not_reached ();
+    }
+    if (script->flags & SWFDEC_SCRIPT_PRELOAD_GLOBAL)
+      fp->vars[preload_reg++] = OBJECT_TO_JSVAL (player->jsobj);
+  }
   /* set up the script */
   startpc = pc = script->buffer->data;
   endpc = startpc + script->buffer->length;
diff --git a/libswfdec/swfdec_script.h b/libswfdec/swfdec_script.h
index 93f59b9..82d2169 100644
--- a/libswfdec/swfdec_script.h
+++ b/libswfdec/swfdec_script.h
@@ -29,6 +29,18 @@ G_BEGIN_DECLS
 
 //typedef struct _SwfdecScript SwfdecScript;
 
+typedef enum {
+  SWFDEC_SCRIPT_PRELOAD_THIS = (1 << 0),
+  SWFDEC_SCRIPT_SUPPRESS_THIS = (1 << 1),
+  SWFDEC_SCRIPT_PRELOAD_ARGS = (1 << 2),
+  SWFDEC_SCRIPT_SUPPRESS_ARGS = (1 << 3),
+  SWFDEC_SCRIPT_PRELOAD_SUPER = (1 << 4),
+  SWFDEC_SCRIPT_SUPPRESS_SUPER = (1 << 5),
+  SWFDEC_SCRIPT_PRELOAD_ROOT = (1 << 6),
+  SWFDEC_SCRIPT_PRELOAD_PARENT = (1 << 7),
+  SWFDEC_SCRIPT_PRELOAD_GLOBAL = (1 << 8)
+} SwfdecScriptFlag;
+
 typedef gboolean (* SwfdecScriptForeachFunc) (gconstpointer bytecode, guint action, 
     const guint8 *data, guint len, gpointer user_data);
 
@@ -41,6 +53,8 @@ struct _SwfdecScript {
   gpointer		debugger;		/* debugger owning us or NULL */
   /* needed by functions */
   SwfdecBuffer *	constant_pool;		/* constant pool action */
+  guint			flags;			/* SwfdecScriptFlags */
+  guint8 *		preloads;		/* NULL or where to preload variables to */
 };
 
 const char *	swfdec_action_get_name		(guint			action);
diff-tree 8a164b9aeff20d0b77f2225135b688cc4d820905 (from 1ef3f0b656af57ba7b8cf08fdefa874d644b97bf)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Feb 16 09:46:19 2007 +0100

    fix invalid code that caused crashes when parsing kerning tables
    
    Only Youtube seems to have those...
    Also updated Copyright headers

diff --git a/libswfdec/swfdec_font.c b/libswfdec/swfdec_font.c
index ac64c22..03157b1 100644
--- a/libswfdec/swfdec_font.c
+++ b/libswfdec/swfdec_font.c
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-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
@@ -237,7 +237,7 @@ tag_func_define_font (SwfdecSwfDecoder *
 static void
 swfdec_font_parse_kerning_table (SwfdecSwfDecoder *s, SwfdecFont *font, gboolean wide_codes)
 {
-  SwfdecBits *bits;
+  SwfdecBits *bits = &s->b;
   guint n_kernings, i;
 
   n_kernings = swfdec_bits_get_u16 (bits);
diff --git a/libswfdec/swfdec_font.h b/libswfdec/swfdec_font.h
index 23ecce4..babfa5a 100644
--- a/libswfdec/swfdec_font.h
+++ b/libswfdec/swfdec_font.h
@@ -1,7 +1,7 @@
 /* Swfdec
  * Copyright (C) 2003-2006 David Schleef <ds at schleef.org>
  *		 2005-2006 Eric Anholt <eric at anholt.net>
- *		      2006 Benjamin Otte <otte at gnome.org>
+ *		 2006-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
diff-tree 1ef3f0b656af57ba7b8cf08fdefa874d644b97bf (from 5e07f4f518cf43351da51a95c43c2fda2016c388)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Feb 15 21:15:23 2007 +0100

    add another test for the width/height changes

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index d931702..d5706dc 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -64,6 +64,8 @@ EXTRA_DIST = \
 	height2.swf.trace \
 	height3.swf \
 	height3.swf.trace \
+	height4.swf \
+	height4.swf.trace \
 	lifetime1.swf \
 	lifetime1.swf.trace \
 	load-4.swf \
diff --git a/test/trace/height4.swf b/test/trace/height4.swf
new file mode 100755
index 0000000..1df1e43
Binary files /dev/null and b/test/trace/height4.swf differ
diff --git a/test/trace/height4.swf.trace b/test/trace/height4.swf.trace
new file mode 100755
index 0000000..8fc6ef9
--- /dev/null
+++ b/test/trace/height4.swf.trace
@@ -0,0 +1,5 @@
+Test rounding of non-integer width and height
+0
+0
+133.3
+133.3
diff-tree 5e07f4f518cf43351da51a95c43c2fda2016c388 (from ab0a07ebac71f88d925f7f50dc5d2ae618cb7fe2)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Feb 15 21:14:44 2007 +0100

    round the width and height instead of just casting
    
    This gets around some irregularities when playing copter.swf

diff --git a/libswfdec/swfdec_js_movie.c b/libswfdec/swfdec_js_movie.c
index d33ba94..10fde07 100644
--- a/libswfdec/swfdec_js_movie.c
+++ b/libswfdec/swfdec_js_movie.c
@@ -818,7 +818,7 @@ mc_width_get (JSContext *cx, JSObject *o
   g_assert (movie);
 
   swfdec_movie_update (movie);
-  d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.x1 - movie->extents.x0));
+  d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.x1 - movie->extents.x0)));
   return JS_NewNumberValue (cx, d, vp);
 }
 
@@ -842,7 +842,7 @@ mc_width_set (JSContext *cx, JSObject *o
   }
   swfdec_movie_update (movie);
   movie->modified = TRUE;
-  cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.x1 - movie->extents.x0));
+  cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.x1 - movie->extents.x0)));
   if (cur != 0) {
     movie->xscale *= d / cur;
   } else {
@@ -864,7 +864,7 @@ mc_height_get (JSContext *cx, JSObject *
   g_assert (movie);
 
   swfdec_movie_update (movie);
-  d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.y1 - movie->extents.y0));
+  d = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.y1 - movie->extents.y0)));
   return JS_NewNumberValue (cx, d, vp);
 }
 
@@ -888,7 +888,7 @@ mc_height_set (JSContext *cx, JSObject *
   }
   swfdec_movie_update (movie);
   movie->modified = TRUE;
-  cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (movie->extents.y1 - movie->extents.y0));
+  cur = SWFDEC_TWIPS_TO_DOUBLE ((SwfdecTwips) (rint (movie->extents.y1 - movie->extents.y0)));
   if (cur != 0) {
     movie->yscale *= d / cur;
   } else {
diff-tree ab0a07ebac71f88d925f7f50dc5d2ae618cb7fe2 (from 5a3b6dc3f4091163b071a50172bfb21de3aa31fd)
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Feb 15 21:13:50 2007 +0100

    add swfscript

diff --git a/test/.gitignore b/test/.gitignore
index 9280a20..eb7f89f 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -12,3 +12,4 @@ dump
 parse
 swfdec-extract
 swfedit
+swfscript


More information about the Swfdec mailing list