[Swfdec] Branch 'as' - 25 commits - libswfdec/Makefile.am libswfdec/swfdec_as_boolean.c libswfdec/swfdec_as_boolean.h libswfdec/swfdec_as_context.c libswfdec/swfdec_as_context.h libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame.h libswfdec/swfdec_as_function.c libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_number.c libswfdec/swfdec_as_number.h libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_script_function.c libswfdec/swfdec_as_strings.c libswfdec/swfdec_as_super.c libswfdec/swfdec_as_super.h libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h libswfdec/swfdec_loader.c libswfdec/swfdec_sprite_movie.c player/swfdec_debug_stack.c player/swfdec_player_manager.c test/trace

Benjamin Otte company at kemper.freedesktop.org
Wed Jul 4 10:01:30 PDT 2007


 libswfdec/Makefile.am                            |    2 
 libswfdec/swfdec_as_boolean.c                    |  113 +++++++++++
 libswfdec/swfdec_as_boolean.h                    |   55 +++++
 libswfdec/swfdec_as_context.c                    |    4 
 libswfdec/swfdec_as_context.h                    |    1 
 libswfdec/swfdec_as_frame.c                      |   11 -
 libswfdec/swfdec_as_frame.h                      |    1 
 libswfdec/swfdec_as_function.c                   |   27 ++
 libswfdec/swfdec_as_interpret.c                  |   44 ++--
 libswfdec/swfdec_as_native_function.c            |   11 +
 libswfdec/swfdec_as_number.c                     |   28 --
 libswfdec/swfdec_as_number.h                     |    3 
 libswfdec/swfdec_as_object.c                     |   62 ++++--
 libswfdec/swfdec_as_object.h                     |    3 
 libswfdec/swfdec_as_script_function.c            |   23 ++
 libswfdec/swfdec_as_strings.c                    |    2 
 libswfdec/swfdec_as_super.c                      |   30 --
 libswfdec/swfdec_as_super.h                      |    1 
 libswfdec/swfdec_as_types.c                      |  165 +++++++++-------
 libswfdec/swfdec_as_types.h                      |    1 
 libswfdec/swfdec_loader.c                        |    2 
 libswfdec/swfdec_sprite_movie.c                  |    6 
 player/swfdec_debug_stack.c                      |    3 
 player/swfdec_player_manager.c                   |   64 ++----
 test/trace/Makefile.am                           |   16 +
 test/trace/call-arguments-5.swf                  |binary
 test/trace/call-arguments-5.swf.trace            |   37 +++
 test/trace/call-arguments-6.swf                  |binary
 test/trace/call-arguments-6.swf.trace            |  232 +++++++++++++++++++++++
 test/trace/call-arguments-7.swf                  |binary
 test/trace/call-arguments-7.swf.trace            |  232 +++++++++++++++++++++++
 test/trace/call-arguments-8.swf                  |binary
 test/trace/call-arguments-8.swf.trace            |  232 +++++++++++++++++++++++
 test/trace/call-arguments.as                     |   19 +
 test/trace/callmethod-undefined-this-5.swf       |binary
 test/trace/callmethod-undefined-this-5.swf.trace |    2 
 test/trace/callmethod-undefined-this-6.swf       |binary
 test/trace/callmethod-undefined-this-6.swf.trace |    2 
 test/trace/callmethod-undefined-this-7.swf       |binary
 test/trace/callmethod-undefined-this-7.swf.trace |    2 
 test/trace/callmethod-undefined-this.as          |    2 
 test/trace/super-calls-6.swf                     |binary
 test/trace/super-calls-6.swf.trace               |   10 
 test/trace/super-calls-7.swf                     |binary
 test/trace/super-calls-7.swf.trace               |   10 
 test/trace/super-calls-8.swf                     |binary
 test/trace/super-calls-8.swf.trace               |   10 
 test/trace/super-calls.as                        |   46 ++++
 48 files changed, 1316 insertions(+), 198 deletions(-)

New commits:
diff-tree 67cc4ffb0e6910ff8080bc6d7ddf41d0df4ed8d6 (from 281f02e28a59dda62d8f207009a00d9f1df987c3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 18:01:15 2007 +0100

    initializing happens after queuein the onLoad script
    
    see onload-childparent.swf test

diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 98d0619..0ae840f 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -1007,12 +1007,12 @@ swfdec_movie_new_for_content (SwfdecMovi
   swfdec_movie_set_static_properties (movie, content->has_transform ? &content->transform : NULL,
       content->has_color_transform ? &content->color_transform : NULL, 
       content->ratio, content->clip_depth, content->events);
-  swfdec_movie_initialize (movie);
   if (SWFDEC_IS_SPRITE_MOVIE (movie)) {
     g_queue_push_tail (player->init_queue, movie);
     g_queue_push_tail (player->construct_queue, movie);
     swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);
   }
+  swfdec_movie_initialize (movie);
 
   return movie;
 }
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 5c40d39..1f088ba 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -266,12 +266,12 @@ swfdec_sprite_movie_perform_place (Swfde
     cur = swfdec_movie_new (player, depth, mov, graphic, name);
     swfdec_movie_set_static_properties (cur, has_transform ? &transform : NULL, 
 	has_ctrans ? &ctrans : NULL, ratio, clip_depth, events);
-    swfdec_movie_initialize (cur);
     if (SWFDEC_IS_SPRITE_MOVIE (cur)) {
       g_queue_push_tail (player->init_queue, cur);
       g_queue_push_tail (player->construct_queue, cur);
       swfdec_movie_queue_script (cur, SWFDEC_EVENT_LOAD);
     }
+    swfdec_movie_initialize (cur);
   }
 
   return TRUE;
diff-tree 281f02e28a59dda62d8f207009a00d9f1df987c3 (from 0ff7c378c287a6ba031d1f1e0c5c641c69808e23)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 17:57:56 2007 +0100

    Check various super calls

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index c1a0256..75c4967 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -738,6 +738,13 @@ EXTRA_DIST = \
 	substring-6.swf.trace \
 	substring-7.swf \
 	substring-7.swf.trace \
+	super-calls.as \
+	super-calls-6.swf \
+	super-calls-6.swf.trace \
+	super-calls-7.swf \
+	super-calls-7.swf.trace \
+	super-calls-8.swf \
+	super-calls-8.swf.trace \
 	tointeger-numbers.as \
 	tointeger-numbers-5.swf \
 	tointeger-numbers-5.swf.trace \
diff --git a/test/trace/super-calls-6.swf b/test/trace/super-calls-6.swf
new file mode 100644
index 0000000..29a7a3f
Binary files /dev/null and b/test/trace/super-calls-6.swf differ
diff --git a/test/trace/super-calls-6.swf.trace b/test/trace/super-calls-6.swf.trace
new file mode 100644
index 0000000..7f249d7
--- /dev/null
+++ b/test/trace/super-calls-6.swf.trace
@@ -0,0 +1,10 @@
+Check various behaviours of the super object
+1
+2
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 3
+foo: 1
+foo: 3
diff --git a/test/trace/super-calls-7.swf b/test/trace/super-calls-7.swf
new file mode 100644
index 0000000..4c9df2f
Binary files /dev/null and b/test/trace/super-calls-7.swf differ
diff --git a/test/trace/super-calls-7.swf.trace b/test/trace/super-calls-7.swf.trace
new file mode 100644
index 0000000..7f249d7
--- /dev/null
+++ b/test/trace/super-calls-7.swf.trace
@@ -0,0 +1,10 @@
+Check various behaviours of the super object
+1
+2
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 3
+foo: 1
+foo: 3
diff --git a/test/trace/super-calls-8.swf b/test/trace/super-calls-8.swf
new file mode 100644
index 0000000..886e99f
Binary files /dev/null and b/test/trace/super-calls-8.swf differ
diff --git a/test/trace/super-calls-8.swf.trace b/test/trace/super-calls-8.swf.trace
new file mode 100644
index 0000000..7f249d7
--- /dev/null
+++ b/test/trace/super-calls-8.swf.trace
@@ -0,0 +1,10 @@
+Check various behaviours of the super object
+1
+2
+3
+foo: 1
+foo: 2
+foo: 3
+foo: 3
+foo: 1
+foo: 3
diff --git a/test/trace/super-calls.as b/test/trace/super-calls.as
new file mode 100644
index 0000000..94d5dce
--- /dev/null
+++ b/test/trace/super-calls.as
@@ -0,0 +1,46 @@
+// makeswf -v 7 -s 200x150 -r 1 -o super-calls.swf super-calls.as
+
+trace ("Check various behaviours of the super object");
+
+function One () {
+  trace (1);
+};
+function Two () {
+  super ();
+  trace (2);
+};
+function Three () {
+  super ();
+  trace (3);
+};
+asm {
+  push "Two"
+  getvariable
+  push "One"
+  getvariable
+  extends
+};
+asm {
+  push "Three"
+  getvariable
+  push "Two"
+  getvariable
+  extends
+};
+One.prototype.foo = function () {
+  trace ("foo: 1");
+};
+Two.prototype.foo = function () {
+  super.foo ();
+  trace ("foo: 2");
+};
+Three.prototype.foo = function () {
+  super.foo (this);
+  trace ("foo: 3");
+};
+x = new Three ();
+x.foo ();
+x.foo.call (this);
+Three.prototype.foo ();
+
+loadMovie ("FSCommand:quit", "");
diff-tree 0ff7c378c287a6ba031d1f1e0c5c641c69808e23 (from 6faffb38275fbc013fd1eef7f861ecf13b0c908a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 17:56:30 2007 +0100

    Flash 6 knows about ActionExtends

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index bbe8060..2cabb64 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -2491,7 +2491,7 @@ const SwfdecActionSpec swfdec_as_actions
   [SWFDEC_AS_ACTION_GREATER] = { "Greater", NULL, 2, 1, { NULL, NULL, NULL, swfdec_action_new_comparison, swfdec_action_new_comparison } },
   [SWFDEC_AS_ACTION_STRING_GREATER] = { "StringGreater", NULL },
   /* version 7 */
-  [SWFDEC_AS_ACTION_EXTENDS] = { "Extends", NULL, 2, 0, { NULL, NULL, NULL, NULL, swfdec_action_extends } },
+  [SWFDEC_AS_ACTION_EXTENDS] = { "Extends", NULL, 2, 0, { NULL, NULL, NULL, swfdec_action_extends, swfdec_action_extends } },
   /* version 3 */
   [SWFDEC_AS_ACTION_GOTO_FRAME] = { "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 } },
   [SWFDEC_AS_ACTION_GET_URL] = { "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 } },
diff-tree 6faffb38275fbc013fd1eef7f861ecf13b0c908a (from 261db8bd06ac55884f3d83689ff2f59322ca0fe3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 17:55:43 2007 +0100

    remove g_prints

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index f762252..bbe8060 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -593,10 +593,9 @@ swfdec_action_call (SwfdecAsContext *cx,
   swfdec_as_function_call (fun, thisp, n_args, swfdec_as_stack_peek (frame->stack, 0), 
       swfdec_as_stack_peek (frame->stack, 1));
   if (use_super) {
-    g_print ("replacing super object\n");
     if (cx->frame->super && SWFDEC_AS_SUPER (frame->super)->object) {
+      SWFDEC_LOG ("replacing super object on frame");
       SWFDEC_AS_SUPER (cx->frame->super)->object = SWFDEC_AS_SUPER (frame->super)->object->prototype;
-      g_print ("  ... done\n");
     }
   }
   return TRUE;
diff-tree 261db8bd06ac55884f3d83689ff2f59322ca0fe3 (from f7a30e1c73af002c06c732d3b357efd1a45998e2)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 17:53:44 2007 +0100

    rework handling of super

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 54347c7..f762252 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -28,6 +28,7 @@
 #include "swfdec_as_script_function.h"
 #include "swfdec_as_stack.h"
 #include "swfdec_as_strings.h"
+#include "swfdec_as_super.h"
 #include "swfdec_as_with.h"
 #include "swfdec_debug.h"
 
@@ -559,7 +560,7 @@ swfdec_action_trace (SwfdecAsContext *cx
 /* stack looks like this: [ function, this, arg1, arg2, ... ] */
 /* stack must be at least 2 elements big */
 static gboolean
-swfdec_action_call (SwfdecAsContext *cx, guint n_args)
+swfdec_action_call (SwfdecAsContext *cx, guint n_args, gboolean use_super)
 {
   SwfdecAsFunction *fun;
   SwfdecAsObject *thisp;
@@ -591,6 +592,13 @@ swfdec_action_call (SwfdecAsContext *cx,
     swfdec_as_stack_pop_n (frame->stack, n_args);
   swfdec_as_function_call (fun, thisp, n_args, swfdec_as_stack_peek (frame->stack, 0), 
       swfdec_as_stack_peek (frame->stack, 1));
+  if (use_super) {
+    g_print ("replacing super object\n");
+    if (cx->frame->super && SWFDEC_AS_SUPER (frame->super)->object) {
+      SWFDEC_AS_SUPER (cx->frame->super)->object = SWFDEC_AS_SUPER (frame->super)->object->prototype;
+      g_print ("  ... done\n");
+    }
+  }
   return TRUE;
 
 error:
@@ -609,19 +617,23 @@ swfdec_action_call_function (SwfdecAsCon
   SwfdecAsObject *obj;
   guint n_args;
   const char *name;
+  SwfdecAsValue *fun, *thisp;
   
   swfdec_as_stack_ensure_size (frame->stack, 2);
   n_args = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (frame->stack, 2));
   name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (frame->stack, 1));
+  thisp = swfdec_as_stack_peek (frame->stack, 2);
+  fun = swfdec_as_stack_peek (frame->stack, 1);
   obj = swfdec_as_frame_find_variable (frame, name);
   if (obj) {
-    SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_peek (frame->stack, 2), obj);
-    swfdec_as_object_get_variable (obj, name, swfdec_as_stack_peek (frame->stack, 1));
+    SWFDEC_AS_VALUE_SET_OBJECT (thisp, obj);
+    swfdec_as_object_get_variable (obj, name, fun);
   } else {
-    SWFDEC_AS_VALUE_SET_NULL (swfdec_as_stack_peek (frame->stack, 2));
-    SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (frame->stack, 1));
+    SWFDEC_AS_VALUE_SET_NULL (thisp);
+    SWFDEC_AS_VALUE_SET_UNDEFINED (fun);
   }
-  if (!swfdec_action_call (cx, n_args)) {
+  if (!swfdec_action_call (cx, n_args, SWFDEC_AS_VALUE_IS_OBJECT (fun) && 
+	SWFDEC_IS_AS_SUPER (SWFDEC_AS_VALUE_GET_OBJECT (fun)))) {
     SWFDEC_ERROR ("no function named %s", name);
   }
 }
@@ -634,16 +646,19 @@ swfdec_action_call_method (SwfdecAsConte
   SwfdecAsObject *obj;
   guint n_args;
   const char *name = NULL;
+  gboolean use_super = FALSE;
   
   swfdec_as_stack_ensure_size (frame->stack, 3);
   obj = swfdec_as_value_to_object (cx, swfdec_as_stack_peek (frame->stack, 2));
   n_args = swfdec_as_value_to_integer (cx, swfdec_as_stack_peek (frame->stack, 3));
   val = swfdec_as_stack_peek (frame->stack, 1);
-  /* FIXME: this is a hack for constructtors calling super - is this correct? */
+  /* FIXME: this is a hack for constructors calling super - is this correct? */
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (val)) {
     SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY);
   }
   if (obj) {
+    if (SWFDEC_IS_AS_SUPER (obj))
+      use_super = TRUE;
     if (SWFDEC_AS_VALUE_IS_STRING (val) && 
 	SWFDEC_AS_VALUE_GET_STRING (val) == SWFDEC_AS_STR_EMPTY) {
       SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (frame->stack, 3));
@@ -660,7 +675,7 @@ swfdec_action_call_method (SwfdecAsConte
     SWFDEC_AS_VALUE_SET_UNDEFINED (swfdec_as_stack_peek (frame->stack, 2));
   }
   swfdec_as_stack_pop (frame->stack);
-  if (!swfdec_action_call (cx, n_args)) {
+  if (!swfdec_action_call (cx, n_args, use_super)) {
     SWFDEC_ERROR ("no function named %s on object %s", name ? name : "unknown", obj ? G_OBJECT_TYPE_NAME(obj) : "unknown");
   }
 }
@@ -1299,7 +1314,7 @@ swfdec_action_start_drag (SwfdecAsContex
   *swfdec_as_stack_peek (stack, 2) = *swfdec_as_stack_peek (stack, 1);
   swfdec_as_object_get_variable (SWFDEC_AS_VALUE_GET_OBJECT (swfdec_as_stack_peek (stack, 2)),
       SWFDEC_AS_STR_startDrag, swfdec_as_stack_peek (stack, 1));
-  swfdec_action_call (cx, n_args);
+  swfdec_action_call (cx, n_args, FALSE);
   /* FIXME: the return value will still be written to this position */
   swfdec_as_stack_pop (stack);
 }
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index bb5b231..c9994f9 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -42,12 +42,11 @@ swfdec_as_super_call (SwfdecAsFunction *
   SwfdecAsFrame *frame;
 
   if (super->object == NULL) {
-    SWFDEC_WARNING ("super () called without a this object.");
+    SWFDEC_WARNING ("super () called without an object.");
     return NULL;
   }
-  if (super->object->prototype == NULL)
-    return NULL;
-  swfdec_as_object_get_variable (super->object->prototype, SWFDEC_AS_STR___constructor__, &val);
+
+  swfdec_as_object_get_variable (super->object, SWFDEC_AS_STR___constructor__, &val);
   if (!SWFDEC_AS_VALUE_IS_OBJECT (&val) ||
       !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val)))
     return NULL;
@@ -76,10 +75,7 @@ swfdec_as_super_get (SwfdecAsObject *obj
     SWFDEC_WARNING ("super () called without a this object.");
     return FALSE;
   }
-  if (super->object->prototype == NULL ||
-      super->object->prototype->prototype == NULL)
-    return FALSE;
-  if (!swfdec_as_object_get_variable (super->object->prototype->prototype, variable, val))
+  if (!swfdec_as_object_get_variable (super->object->prototype, variable, val))
     return FALSE;
   *flags = 0;
   return TRUE;
@@ -136,22 +132,10 @@ swfdec_as_super_new (SwfdecAsFrame *fram
   if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsSuper)))
     return NULL;
   ret = g_object_new (SWFDEC_TYPE_AS_SUPER, NULL);
-  super = SWFDEC_AS_SUPER (ret);
-  if (frame->thisp) {
-    SwfdecAsValue val;
-    super->object = frame->thisp;
-    swfdec_as_object_get_variable (frame->thisp, SWFDEC_AS_STR___proto__, &val);
-    if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
-      SwfdecAsObject *proto = SWFDEC_AS_VALUE_GET_OBJECT (&val);
-      swfdec_as_object_get_variable (proto, SWFDEC_AS_STR_constructor, &val);
-      if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
-	super->constructor = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val);
-	if (!SWFDEC_IS_AS_FUNCTION (super->constructor))
-	  super->constructor = NULL;
-      }
-    }
-  }
   swfdec_as_object_add (ret, context, sizeof (SwfdecAsSuper));
+  super = SWFDEC_AS_SUPER (ret);
+  if (frame->thisp)
+    super->object = frame->thisp->prototype;
   return ret;
 }
 
diff --git a/libswfdec/swfdec_as_super.h b/libswfdec/swfdec_as_super.h
index 2545fe7..1870307 100644
--- a/libswfdec/swfdec_as_super.h
+++ b/libswfdec/swfdec_as_super.h
@@ -38,7 +38,6 @@ typedef struct _SwfdecAsSuperClass Swfde
 struct _SwfdecAsSuper {
   SwfdecAsFunction	function;
 
-  SwfdecAsFunction *	constructor;	/* super function or NULL */
   SwfdecAsObject *	object;		/* object super was called on or NULL */
 };
 
diff-tree f7a30e1c73af002c06c732d3b357efd1a45998e2 (from 1a846b35b6185db8b0a2905a6f9a5e432a6a5340)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 17:53:32 2007 +0100

    keep a reference to the super object in the SwfdecAsFrame

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 4dc861c..1caf849 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -69,6 +69,8 @@ swfdec_as_frame_mark (SwfdecAsObject *ob
     swfdec_as_object_mark (SWFDEC_AS_OBJECT (frame->scope));
   if (frame->thisp)
     swfdec_as_object_mark (frame->thisp);
+  if (frame->super)
+    swfdec_as_object_mark (frame->super);
   swfdec_as_object_mark (frame->target);
   swfdec_as_object_mark (frame->original_target);
   if (frame->function)
@@ -356,12 +358,12 @@ swfdec_as_frame_preload (SwfdecAsFrame *
     }
   }
   if (!(script->flags & SWFDEC_SCRIPT_SUPPRESS_SUPER)) {
-    SwfdecAsObject *super = swfdec_as_super_new (frame);
-    if (super) {
+    frame->super = swfdec_as_super_new (frame);
+    if (frame->super) {
       if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER) {
-	SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], super);
+	SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], frame->super);
       } else {
-	SWFDEC_AS_VALUE_SET_OBJECT (&val, super);
+	SWFDEC_AS_VALUE_SET_OBJECT (&val, frame->super);
 	swfdec_as_object_set_variable (object, SWFDEC_AS_STR_super, &val);
       }
     }
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index 36756fb..78e90cc 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -41,6 +41,7 @@ struct _SwfdecAsFrame {
   SwfdecAsFrame *	next;		/* next frame (FIXME: keep a list in the context instead?) */
   SwfdecAsFunction *	function;	/* function we're executing or NULL if toplevel */
   SwfdecAsObject *	thisp;		/* this object in current frame or NULL if none */
+  SwfdecAsObject *	super;		/* super object in current frame or NULL if none */
   gboolean		construct;	/* TRUE if this is the constructor for thisp */
   SwfdecAsValue *	return_value;	/* pointer to where to store the return value */
   guint			argc;		/* number of arguments */
diff-tree 1a846b35b6185db8b0a2905a6f9a5e432a6a5340 (from 156c694a5260217ae7259e4b65b6d1618e2c37a3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 16:16:33 2007 +0100

    this property is now unused

diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index a416b0e..3dc1ad8 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -70,7 +70,6 @@ struct _SwfdecAsContext {
   SwfdecAsObject *	Object;		/* Object */
   SwfdecAsObject *	Object_prototype;	/* Object.prototype */
   SwfdecAsObject *	Array;		/* Array */
-  SwfdecAsObject *	Number;		/* Number */
 };
 
 struct _SwfdecAsContextClass {
diff-tree 156c694a5260217ae7259e4b65b6d1618e2c37a3 (from 00094725820589f061c3df3ddcdd3d67cbfccf5d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 15:45:59 2007 +0100

    add Boolean type and lookup objects correctly

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index e91b587..77e166e 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -21,6 +21,7 @@ lib_LTLIBRARIES = libswfdec- at SWFDEC_MAJO
 
 libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES = \
 	swfdec_as_array.c \
+	swfdec_as_boolean.c \
 	swfdec_as_context.c \
 	swfdec_as_frame.c \
 	swfdec_as_function.c \
@@ -132,6 +133,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@include_HEA
 
 noinst_HEADERS = \
 	swfdec_as_array.h \
+	swfdec_as_boolean.h \
 	swfdec_as_frame.h \
 	swfdec_as_function.h \
 	swfdec_as_interpret.h \
diff --git a/libswfdec/swfdec_as_boolean.c b/libswfdec/swfdec_as_boolean.c
new file mode 100644
index 0000000..da45473
--- /dev/null
+++ b/libswfdec/swfdec_as_boolean.c
@@ -0,0 +1,113 @@
+/* Swfdec
+ * 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 <math.h>
+
+#include "swfdec_as_boolean.h"
+#include "swfdec_as_context.h"
+#include "swfdec_as_frame.h"
+#include "swfdec_as_native_function.h"
+#include "swfdec_as_strings.h"
+#include "swfdec_debug.h"
+
+G_DEFINE_TYPE (SwfdecAsBoolean, swfdec_as_boolean, SWFDEC_TYPE_AS_OBJECT)
+
+static void
+swfdec_as_boolean_class_init (SwfdecAsBooleanClass *klass)
+{
+}
+
+static void
+swfdec_as_boolean_init (SwfdecAsBoolean *boolean)
+{
+}
+
+/*** AS CODE ***/
+
+static void
+swfdec_as_boolean_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+  gboolean b;
+
+  if (argc > 0) {
+    b = swfdec_as_value_to_boolean (object->context, &argv[0]);
+  } else {
+    b = FALSE;
+  }
+
+  if (cx->frame->construct) {
+    SWFDEC_AS_BOOLEAN (object)->boolean = b;
+    SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
+  } else {
+    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, b);
+  }
+}
+
+static void
+swfdec_as_boolean_toString (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+  SwfdecAsBoolean *b = SWFDEC_AS_BOOLEAN (object);
+  
+  SWFDEC_AS_VALUE_SET_STRING (ret, b->boolean ? SWFDEC_AS_STR_true : SWFDEC_AS_STR_false);
+}
+
+static void
+swfdec_as_boolean_valueOf (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+  SwfdecAsBoolean *b = SWFDEC_AS_BOOLEAN (object);
+
+  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, b->boolean);
+}
+
+void
+swfdec_as_boolean_init_context (SwfdecAsContext *context, guint version)
+{
+  SwfdecAsObject *boolean, *proto;
+  SwfdecAsValue val;
+
+  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+
+  boolean = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
+      SWFDEC_AS_STR_Boolean, SWFDEC_TYPE_AS_BOOLEAN, swfdec_as_boolean_construct, 0));
+  if (!boolean)
+    return;
+  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (boolean), SWFDEC_TYPE_AS_BOOLEAN);
+  swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (boolean), SWFDEC_TYPE_AS_BOOLEAN);
+  proto = swfdec_as_object_new (context);
+  /* set the right properties on the Boolean object */
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
+  swfdec_as_object_set_variable (boolean, SWFDEC_AS_STR_prototype, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
+  swfdec_as_object_set_variable (boolean, SWFDEC_AS_STR_constructor, &val);
+  /* set the right properties on the Boolean.prototype object */
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR___proto__, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, boolean);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_toString, SWFDEC_TYPE_AS_BOOLEAN, swfdec_as_boolean_toString, 0);
+  swfdec_as_object_add_function (proto, SWFDEC_AS_STR_valueOf, SWFDEC_TYPE_AS_BOOLEAN, swfdec_as_boolean_valueOf, 0);
+}
+
diff --git a/libswfdec/swfdec_as_boolean.h b/libswfdec/swfdec_as_boolean.h
new file mode 100644
index 0000000..47ec511
--- /dev/null
+++ b/libswfdec/swfdec_as_boolean.h
@@ -0,0 +1,55 @@
+/* Swfdec
+ * 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_BOOLEAN_H_
+#define _SWFDEC_AS_BOOLEAN_H_
+
+#include <libswfdec/swfdec_as_object.h>
+#include <libswfdec/swfdec_as_types.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecAsBoolean SwfdecAsBoolean;
+typedef struct _SwfdecAsBooleanClass SwfdecAsBooleanClass;
+
+#define SWFDEC_TYPE_AS_BOOLEAN                    (swfdec_as_boolean_get_type())
+#define SWFDEC_IS_AS_BOOLEAN(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_AS_BOOLEAN))
+#define SWFDEC_IS_AS_BOOLEAN_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_AS_BOOLEAN))
+#define SWFDEC_AS_BOOLEAN(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_AS_BOOLEAN, SwfdecAsBoolean))
+#define SWFDEC_AS_BOOLEAN_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_AS_BOOLEAN, SwfdecAsBooleanClass))
+#define SWFDEC_AS_BOOLEAN_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_AS_BOOLEAN, SwfdecAsBooleanClass))
+
+struct _SwfdecAsBoolean {
+  SwfdecAsObject	object;
+
+  double		boolean;		/* boolean represented by this boolean object */
+};
+
+struct _SwfdecAsBooleanClass {
+  SwfdecAsObjectClass	object_class;
+};
+
+GType		swfdec_as_boolean_get_type	(void);
+
+void		swfdec_as_boolean_init_context	(SwfdecAsContext *	context,
+						 guint			version);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index a8d1454..9257371 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include "swfdec_as_context.h"
 #include "swfdec_as_array.h"
+#include "swfdec_as_boolean.h"
 #include "swfdec_as_frame.h"
 #include "swfdec_as_function.h"
 #include "swfdec_as_interpret.h"
@@ -1020,6 +1021,7 @@ swfdec_as_context_startup (SwfdecAsConte
   swfdec_as_context_init_global (context, version);
   swfdec_as_array_init_context (context, version);
   /* define the type objects */
+  swfdec_as_boolean_init_context (context, version);
   swfdec_as_number_init_context (context, version);
   swfdec_as_string_init_context (context, version);
   /* define the rest */
diff --git a/libswfdec/swfdec_as_number.c b/libswfdec/swfdec_as_number.c
index ba611bf..632d25d 100644
--- a/libswfdec/swfdec_as_number.c
+++ b/libswfdec/swfdec_as_number.c
@@ -42,31 +42,6 @@ swfdec_as_number_init (SwfdecAsNumber *n
 {
 }
 
-/**
- * swfdec_as_number_new:
- * @context: a #SwfdecAsContext
- * @number: value of the number
- *
- * Creates a new #SwfdecAsNumber. This is the same as executing the Actionscript
- * code "new Number ()"
- *
- * Returns: the new number or %NULL on OOM.
- **/
-SwfdecAsObject *
-swfdec_as_number_new (SwfdecAsContext *context, double number)
-{
-  SwfdecAsObject *ret;
-  SwfdecAsValue val;
-
-  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
-  g_return_val_if_fail (context->Number != NULL, NULL);
-  
-  SWFDEC_AS_VALUE_SET_NUMBER (&val, number);
-  ret = swfdec_as_object_create (SWFDEC_AS_FUNCTION (context->Number), 1, &val, FALSE);
-  swfdec_as_context_run (context);
-  return ret;
-}
-
 /*** AS CODE ***/
 
 static void
@@ -128,7 +103,6 @@ swfdec_as_number_init_context (SwfdecAsC
   if (!number)
     return;
   swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (number), SWFDEC_TYPE_AS_NUMBER);
-  context->Number = number;
   swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (number), 
       SWFDEC_TYPE_AS_NUMBER);
   proto = swfdec_as_object_new (context);
diff --git a/libswfdec/swfdec_as_number.h b/libswfdec/swfdec_as_number.h
index b4ec697..52a1fd9 100644
--- a/libswfdec/swfdec_as_number.h
+++ b/libswfdec/swfdec_as_number.h
@@ -47,9 +47,6 @@ struct _SwfdecAsNumberClass {
 
 GType		swfdec_as_number_get_type	(void);
 
-SwfdecAsObject *swfdec_as_number_new		(SwfdecAsContext *	context,
-						 double			num);
-
 void		swfdec_as_number_init_context	(SwfdecAsContext *	context,
 						 guint			version);
 
diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index ee9089a..a5e8553 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -223,6 +223,7 @@ const char swfdec_as_strings[] = 
   SWFDEC_AS_CONSTANT_STRING ("bytesTotal")
   SWFDEC_AS_CONSTANT_STRING ("indexOf")
   SWFDEC_AS_CONSTANT_STRING ("call")
+  SWFDEC_AS_CONSTANT_STRING ("Boolean")
   /* add more here */
 ;
 
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 38a636f..65e67c9 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -517,7 +517,10 @@ swfdec_as_value_to_integer (SwfdecAsCont
 SwfdecAsObject *
 swfdec_as_value_to_object (SwfdecAsContext *context, const SwfdecAsValue *value)
 {
+  SwfdecAsFunction *fun;
+  SwfdecAsObject *ret;
   SwfdecAsValue val;
+  const char *s;
 
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
   g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), NULL);
@@ -527,92 +530,91 @@ swfdec_as_value_to_object (SwfdecAsConte
     case SWFDEC_AS_TYPE_NULL:
       return NULL;
     case SWFDEC_AS_TYPE_NUMBER:
-      return swfdec_as_number_new (context, SWFDEC_AS_VALUE_GET_NUMBER (value));
+      s = SWFDEC_AS_STR_Number;
+      break;
     case SWFDEC_AS_TYPE_STRING:
-      {
-	SwfdecAsFunction *fun;
-	SwfdecAsObject *ret;
-
-	swfdec_as_object_get_variable (context->global, SWFDEC_AS_STR_String, &val);
-	if (!SWFDEC_AS_VALUE_IS_OBJECT (&val) ||
-	    !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val)))
-	  return NULL;
-	ret = swfdec_as_object_create (fun, 1, value, TRUE);
-	swfdec_as_context_run (context);
-	return ret;
-      }
+      s = SWFDEC_AS_STR_String;
+      break;
     case SWFDEC_AS_TYPE_BOOLEAN:
-      SWFDEC_ERROR ("FIXME: implement Boolean");
-      return NULL;
+      s = SWFDEC_AS_STR_Boolean;
+      break;
     case SWFDEC_AS_TYPE_OBJECT:
       return SWFDEC_AS_VALUE_GET_OBJECT (value);
     default:
       g_assert_not_reached ();
       return NULL;
   }
+
+  swfdec_as_object_get_variable (context->global, s, &val);
+  if (!SWFDEC_AS_VALUE_IS_OBJECT (&val) ||
+      !SWFDEC_IS_AS_FUNCTION (fun = (SwfdecAsFunction *) SWFDEC_AS_VALUE_GET_OBJECT (&val)))
+    return NULL;
+  ret = swfdec_as_object_create (fun, 1, value, TRUE);
+  swfdec_as_context_run (context);
+  return ret;
 }
 
 /**
- * swfdec_as_value_to_boolean:
- * @context: a #SwfdecAsContext
- * @value: value to convert
- *
- * Converts the given value to a boolean according to Flash's rules. Note that
- * these rules changed significantly for strings between Flash 6 and 7.
- *
- * Returns: either %TRUE or %FALSE.
- **/
+* swfdec_as_value_to_boolean:
+* @context: a #SwfdecAsContext
+* @value: value to convert
+*
+* Converts the given value to a boolean according to Flash's rules. Note that
+* these rules changed significantly for strings between Flash 6 and 7.
+*
+* Returns: either %TRUE or %FALSE.
+**/
 gboolean
 swfdec_as_value_to_boolean (SwfdecAsContext *context, const SwfdecAsValue *value)
 {
-  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
-  g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), FALSE);
+g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
+g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), FALSE);
 
-  /* FIXME: what do we do when called in flash 4? */
-  switch (value->type) {
-    case SWFDEC_AS_TYPE_UNDEFINED:
-    case SWFDEC_AS_TYPE_NULL:
-      return FALSE;
-    case SWFDEC_AS_TYPE_BOOLEAN:
-      return SWFDEC_AS_VALUE_GET_BOOLEAN (value);
-    case SWFDEC_AS_TYPE_NUMBER:
-      {
-	double d = SWFDEC_AS_VALUE_GET_NUMBER (value);
-	return d != 0.0 && !isnan (d);
-      }
-    case SWFDEC_AS_TYPE_STRING:
-      if (context->version <= 6) {
-	double d = swfdec_as_value_to_number (context, value);
-	return d != 0.0 && !isnan (d);
-      } else {
-	return SWFDEC_AS_VALUE_GET_STRING (value) != SWFDEC_AS_STR_EMPTY;
-      }
-    case SWFDEC_AS_TYPE_OBJECT:
-      return TRUE;
-    default:
-      g_assert_not_reached ();
-      return FALSE;
-  }
+/* FIXME: what do we do when called in flash 4? */
+switch (value->type) {
+case SWFDEC_AS_TYPE_UNDEFINED:
+case SWFDEC_AS_TYPE_NULL:
+return FALSE;
+case SWFDEC_AS_TYPE_BOOLEAN:
+return SWFDEC_AS_VALUE_GET_BOOLEAN (value);
+case SWFDEC_AS_TYPE_NUMBER:
+{
+  double d = SWFDEC_AS_VALUE_GET_NUMBER (value);
+  return d != 0.0 && !isnan (d);
+}
+case SWFDEC_AS_TYPE_STRING:
+if (context->version <= 6) {
+  double d = swfdec_as_value_to_number (context, value);
+  return d != 0.0 && !isnan (d);
+} else {
+  return SWFDEC_AS_VALUE_GET_STRING (value) != SWFDEC_AS_STR_EMPTY;
+}
+case SWFDEC_AS_TYPE_OBJECT:
+return TRUE;
+default:
+g_assert_not_reached ();
+return FALSE;
+}
 }
 
 /**
- * swfdec_as_value_to_primitive:
- * @context: a #SwfdecAsContext
- * @value: value to convert
- *
- * Tries to convert the given @value inline to its primitive value. Primitive 
- * values are values that are not objects. If the value is an object, the 
- * object's valueOf function is called. If the result of that function is still 
- * an object, it is returned nonetheless.
- **/
+* swfdec_as_value_to_primitive:
+* @context: a #SwfdecAsContext
+* @value: value to convert
+*
+* Tries to convert the given @value inline to its primitive value. Primitive 
+* values are values that are not objects. If the value is an object, the 
+* object's valueOf function is called. If the result of that function is still 
+* an object, it is returned nonetheless.
+**/
 void
 swfdec_as_value_to_primitive (SwfdecAsValue *value)
 {
-  g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
+g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
 
-  if (SWFDEC_AS_VALUE_IS_OBJECT (value) && !SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (value))) {
-    swfdec_as_object_call (SWFDEC_AS_VALUE_GET_OBJECT (value), SWFDEC_AS_STR_valueOf,
-	0, NULL, value);
-  }
+if (SWFDEC_AS_VALUE_IS_OBJECT (value) && !SWFDEC_IS_MOVIE (SWFDEC_AS_VALUE_GET_OBJECT (value))) {
+swfdec_as_object_call (SWFDEC_AS_VALUE_GET_OBJECT (value), SWFDEC_AS_STR_valueOf,
+  0, NULL, value);
+}
 }
 
diff-tree 00094725820589f061c3df3ddcdd3d67cbfccf5d (from fb9f57d06862db67545cfd8ab3145eb74f159066)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 15:27:14 2007 +0100

    don't call functions on objects that may be NULL

diff --git a/libswfdec/swfdec_as_number.c b/libswfdec/swfdec_as_number.c
index 5127102..ba611bf 100644
--- a/libswfdec/swfdec_as_number.c
+++ b/libswfdec/swfdec_as_number.c
@@ -125,9 +125,9 @@ swfdec_as_number_init_context (SwfdecAsC
 
   number = SWFDEC_AS_OBJECT (swfdec_as_object_add_function (context->global,
       SWFDEC_AS_STR_Number, SWFDEC_TYPE_AS_NUMBER, swfdec_as_number_construct, 0));
-  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (number), SWFDEC_TYPE_AS_NUMBER);
   if (!number)
     return;
+  swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (number), SWFDEC_TYPE_AS_NUMBER);
   context->Number = number;
   swfdec_as_native_function_set_object_type (SWFDEC_AS_NATIVE_FUNCTION (number), 
       SWFDEC_TYPE_AS_NUMBER);
diff-tree fb9f57d06862db67545cfd8ab3145eb74f159066 (from 7c4c596835b0d60e5c221fd853ee6ce5f389af57)
Author: Andreas Henriksson <andreas at fatal.se>
Date:   Wed Jul 4 15:19:56 2007 +0100

    allow comma in URLs

diff --git a/libswfdec/swfdec_loader.c b/libswfdec/swfdec_loader.c
index 8f8db69..ab70734 100644
--- a/libswfdec/swfdec_loader.c
+++ b/libswfdec/swfdec_loader.c
@@ -605,7 +605,7 @@ swfdec_loader_data_type_get_extension (S
 /*** X-WWW-FORM-URLENCODED ***/
 
 /* if speed ever gets an issue, use a 256 byte array instead of strchr */
-static const char *urlencode_unescaped="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.:/()'";
+static const char *urlencode_unescaped="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.,:/()'";
 static void
 swfdec_urlencode_append_string (GString *str, const char *s)
 {
diff-tree 7c4c596835b0d60e5c221fd853ee6ce5f389af57 (from 9aa53abfbf4fea64ae44897ac2128c2c7903391b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 15:16:56 2007 +0100

    add test for Function.call ()

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 89172ca..c1a0256 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -57,6 +57,15 @@ EXTRA_DIST = \
 	bitwise-6.swf.trace \
 	bitwise-7.swf \
 	bitwise-7.swf.trace \
+	call-arguments.as \
+	call-arguments-5.swf \
+	call-arguments-5.swf.trace \
+	call-arguments-6.swf \
+	call-arguments-6.swf.trace \
+	call-arguments-7.swf \
+	call-arguments-7.swf.trace \
+	call-arguments-8.swf \
+	call-arguments-8.swf.trace \
 	callfunction-stack.as \
 	callfunction-stack.swf \
 	callfunction-stack.swf.trace \
diff --git a/test/trace/call-arguments-5.swf b/test/trace/call-arguments-5.swf
new file mode 100644
index 0000000..5d4fdf8
Binary files /dev/null and b/test/trace/call-arguments-5.swf differ
diff --git a/test/trace/call-arguments-5.swf.trace b/test/trace/call-arguments-5.swf.trace
new file mode 100644
index 0000000..c8987c3
--- /dev/null
+++ b/test/trace/call-arguments-5.swf.trace
@@ -0,0 +1,37 @@
+Check arguments handling in Function.call
+valueOf called
+toString called
+toString called with 
+valueOf called with 
+0: valueOf!
+1: valueOf!
+2: valueOf!
+3: valueOf!
+4: valueOf!
+5: valueOf!
+6: valueOf!
+7: valueOf!
+8: valueOf!
+9: valueOf!
+10: valueOf!
+11: valueOf!
+12: valueOf!
+13: valueOf!
+14: valueOf!
+15: valueOf!
+16: valueOf!
+17: valueOf!
+18: valueOf!
+19: valueOf!
+20: valueOf!
+21: valueOf!
+21: toString!
+22: valueOf!
+23: valueOf!
+23: toString!
+24: valueOf!
+24: toString!
+25: valueOf!
+25: toString!
+26: valueOf!
+26: toString!
diff --git a/test/trace/call-arguments-6.swf b/test/trace/call-arguments-6.swf
new file mode 100644
index 0000000..9ed0ec2
Binary files /dev/null and b/test/trace/call-arguments-6.swf differ
diff --git a/test/trace/call-arguments-6.swf.trace b/test/trace/call-arguments-6.swf.trace
new file mode 100644
index 0000000..7bad939
--- /dev/null
+++ b/test/trace/call-arguments-6.swf.trace
@@ -0,0 +1,232 @@
+Check arguments handling in Function.call
+valueOf called
+toString called
+toString called with 
+valueOf called with 
+0: valueOf!
+1: valueOf!
+2: valueOf!
+3: valueOf!
+4: valueOf!
+5: valueOf!
+6: valueOf!
+7: valueOf!
+8: valueOf!
+9: valueOf!
+10: valueOf!
+11: valueOf!
+12: valueOf!
+13: valueOf!
+14: valueOf!
+15: valueOf!
+16: valueOf!
+17: valueOf!
+18: valueOf!
+19: valueOf!
+20: valueOf!
+21: valueOf!
+21: toString!
+22: valueOf!
+22: toString!
+23: valueOf!
+23: toString!
+24: valueOf!
+24: toString!
+25: valueOf!
+25: toString!
+26: valueOf!
+26: toString!
+[type Object]
+undefined
+42
+[type Object]
+hi
+42
+[type Object]
+hi
+42
+true
+hi
+42
+false
+hi
+42
+0
+hi
+42
+1
+hi
+42
+0.5
+hi
+42
+-1
+hi
+42
+-0.5
+hi
+42
+Infinity
+hi
+42
+-Infinity
+hi
+42
+NaN
+hi
+42
+
+hi
+42
+0
+hi
+42
+-0
+hi
+42
+0.0
+hi
+42
+1
+hi
+42
+Hello World!
+hi
+42
+true
+hi
+42
+_level0
+hi
+42
+_level0
+hi
+42
+[object Object]
+hi
+42
+[type Function]
+hi
+42
+toString called
+[type Object]
+hi
+42
+toString called with 
+[type Object]
+hi
+42
+[object Object]
+hi
+42
+[type Object]
+hi
+42
+0: toString!
+[type Object]
+hi
+42
+1: toString!
+[type Object]
+hi
+42
+2: toString!
+[type Object]
+hi
+42
+3: toString!
+[type Object]
+hi
+42
+4: toString!
+[type Object]
+hi
+42
+5: toString!
+[type Object]
+hi
+42
+6: toString!
+[type Object]
+hi
+42
+7: toString!
+[type Object]
+hi
+42
+8: toString!
+[type Object]
+hi
+42
+9: toString!
+[type Object]
+hi
+42
+10: toString!
+[type Object]
+hi
+42
+11: toString!
+[type Object]
+hi
+42
+12: toString!
+
+hi
+42
+13: toString!
+0
+hi
+42
+14: toString!
+-0
+hi
+42
+15: toString!
+0.0
+hi
+42
+16: toString!
+1
+hi
+42
+17: toString!
+Hello World!
+hi
+42
+18: toString!
+true
+hi
+42
+19: toString!
+_level0
+hi
+42
+20: toString!
+[type Object]
+hi
+42
+21: toString!
+[type Object]
+hi
+42
+22: toString!
+[type Object]
+hi
+42
+23: toString!
+[type Object]
+hi
+42
+24: toString!
+[type Object]
+hi
+42
+25: toString!
+[type Object]
+hi
+42
+26: toString!
+[type Object]
+hi
+42
diff --git a/test/trace/call-arguments-7.swf b/test/trace/call-arguments-7.swf
new file mode 100644
index 0000000..2991704
Binary files /dev/null and b/test/trace/call-arguments-7.swf differ
diff --git a/test/trace/call-arguments-7.swf.trace b/test/trace/call-arguments-7.swf.trace
new file mode 100644
index 0000000..7bad939
--- /dev/null
+++ b/test/trace/call-arguments-7.swf.trace
@@ -0,0 +1,232 @@
+Check arguments handling in Function.call
+valueOf called
+toString called
+toString called with 
+valueOf called with 
+0: valueOf!
+1: valueOf!
+2: valueOf!
+3: valueOf!
+4: valueOf!
+5: valueOf!
+6: valueOf!
+7: valueOf!
+8: valueOf!
+9: valueOf!
+10: valueOf!
+11: valueOf!
+12: valueOf!
+13: valueOf!
+14: valueOf!
+15: valueOf!
+16: valueOf!
+17: valueOf!
+18: valueOf!
+19: valueOf!
+20: valueOf!
+21: valueOf!
+21: toString!
+22: valueOf!
+22: toString!
+23: valueOf!
+23: toString!
+24: valueOf!
+24: toString!
+25: valueOf!
+25: toString!
+26: valueOf!
+26: toString!
+[type Object]
+undefined
+42
+[type Object]
+hi
+42
+[type Object]
+hi
+42
+true
+hi
+42
+false
+hi
+42
+0
+hi
+42
+1
+hi
+42
+0.5
+hi
+42
+-1
+hi
+42
+-0.5
+hi
+42
+Infinity
+hi
+42
+-Infinity
+hi
+42
+NaN
+hi
+42
+
+hi
+42
+0
+hi
+42
+-0
+hi
+42
+0.0
+hi
+42
+1
+hi
+42
+Hello World!
+hi
+42
+true
+hi
+42
+_level0
+hi
+42
+_level0
+hi
+42
+[object Object]
+hi
+42
+[type Function]
+hi
+42
+toString called
+[type Object]
+hi
+42
+toString called with 
+[type Object]
+hi
+42
+[object Object]
+hi
+42
+[type Object]
+hi
+42
+0: toString!
+[type Object]
+hi
+42
+1: toString!
+[type Object]
+hi
+42
+2: toString!
+[type Object]
+hi
+42
+3: toString!
+[type Object]
+hi
+42
+4: toString!
+[type Object]
+hi
+42
+5: toString!
+[type Object]
+hi
+42
+6: toString!
+[type Object]
+hi
+42
+7: toString!
+[type Object]
+hi
+42
+8: toString!
+[type Object]
+hi
+42
+9: toString!
+[type Object]
+hi
+42
+10: toString!
+[type Object]
+hi
+42
+11: toString!
+[type Object]
+hi
+42
+12: toString!
+
+hi
+42
+13: toString!
+0
+hi
+42
+14: toString!
+-0
+hi
+42
+15: toString!
+0.0
+hi
+42
+16: toString!
+1
+hi
+42
+17: toString!
+Hello World!
+hi
+42
+18: toString!
+true
+hi
+42
+19: toString!
+_level0
+hi
+42
+20: toString!
+[type Object]
+hi
+42
+21: toString!
+[type Object]
+hi
+42
+22: toString!
+[type Object]
+hi
+42
+23: toString!
+[type Object]
+hi
+42
+24: toString!
+[type Object]
+hi
+42
+25: toString!
+[type Object]
+hi
+42
+26: toString!
+[type Object]
+hi
+42
diff --git a/test/trace/call-arguments-8.swf b/test/trace/call-arguments-8.swf
new file mode 100644
index 0000000..280d62a
Binary files /dev/null and b/test/trace/call-arguments-8.swf differ
diff --git a/test/trace/call-arguments-8.swf.trace b/test/trace/call-arguments-8.swf.trace
new file mode 100644
index 0000000..7bad939
--- /dev/null
+++ b/test/trace/call-arguments-8.swf.trace
@@ -0,0 +1,232 @@
+Check arguments handling in Function.call
+valueOf called
+toString called
+toString called with 
+valueOf called with 
+0: valueOf!
+1: valueOf!
+2: valueOf!
+3: valueOf!
+4: valueOf!
+5: valueOf!
+6: valueOf!
+7: valueOf!
+8: valueOf!
+9: valueOf!
+10: valueOf!
+11: valueOf!
+12: valueOf!
+13: valueOf!
+14: valueOf!
+15: valueOf!
+16: valueOf!
+17: valueOf!
+18: valueOf!
+19: valueOf!
+20: valueOf!
+21: valueOf!
+21: toString!
+22: valueOf!
+22: toString!
+23: valueOf!
+23: toString!
+24: valueOf!
+24: toString!
+25: valueOf!
+25: toString!
+26: valueOf!
+26: toString!
+[type Object]
+undefined
+42
+[type Object]
+hi
+42
+[type Object]
+hi
+42
+true
+hi
+42
+false
+hi
+42
+0
+hi
+42
+1
+hi
+42
+0.5
+hi
+42
+-1
+hi
+42
+-0.5
+hi
+42
+Infinity
+hi
+42
+-Infinity
+hi
+42
+NaN
+hi
+42
+
+hi
+42
+0
+hi
+42
+-0
+hi
+42
+0.0
+hi
+42
+1
+hi
+42
+Hello World!
+hi
+42
+true
+hi
+42
+_level0
+hi
+42
+_level0
+hi
+42
+[object Object]
+hi
+42
+[type Function]
+hi
+42
+toString called
+[type Object]
+hi
+42
+toString called with 
+[type Object]
+hi
+42
+[object Object]
+hi
+42
+[type Object]
+hi
+42
+0: toString!
+[type Object]
+hi
+42
+1: toString!
+[type Object]
+hi
+42
+2: toString!
+[type Object]
+hi
+42
+3: toString!
+[type Object]
+hi
+42
+4: toString!
+[type Object]
+hi
+42
+5: toString!
+[type Object]
+hi
+42
+6: toString!
+[type Object]
+hi
+42
+7: toString!
+[type Object]
+hi
+42
+8: toString!
+[type Object]
+hi
+42
+9: toString!
+[type Object]
+hi
+42
+10: toString!
+[type Object]
+hi
+42
+11: toString!
+[type Object]
+hi
+42
+12: toString!
+
+hi
+42
+13: toString!
+0
+hi
+42
+14: toString!
+-0
+hi
+42
+15: toString!
+0.0
+hi
+42
+16: toString!
+1
+hi
+42
+17: toString!
+Hello World!
+hi
+42
+18: toString!
+true
+hi
+42
+19: toString!
+_level0
+hi
+42
+20: toString!
+[type Object]
+hi
+42
+21: toString!
+[type Object]
+hi
+42
+22: toString!
+[type Object]
+hi
+42
+23: toString!
+[type Object]
+hi
+42
+24: toString!
+[type Object]
+hi
+42
+25: toString!
+[type Object]
+hi
+42
+26: toString!
+[type Object]
+hi
+42
diff --git a/test/trace/call-arguments.as b/test/trace/call-arguments.as
new file mode 100644
index 0000000..2356baa
--- /dev/null
+++ b/test/trace/call-arguments.as
@@ -0,0 +1,19 @@
+// makeswf -v 7 -s 200x150 -r 1 -o call-arguments.swf call-arguents.as
+
+trace ("Check arguments handling in Function.call");
+
+#include "values.as"
+
+function foo (a) {
+  trace (this);
+  trace (a);
+  this.x = 42;
+  trace (this.x);
+};
+
+foo.call ();
+for (i = 0; i < values.length; i++) {
+  foo.call (values[i], "hi");
+};
+
+loadMovie ("FSCommand:quit", "");
diff-tree 9aa53abfbf4fea64ae44897ac2128c2c7903391b (from 14343adf3d551aec7aad37ddcbd5170499d14957)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 15:14:06 2007 +0100

    implement Function.call()

diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 22e65b1..c817379 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -88,7 +88,8 @@ swfdec_as_function_call (SwfdecAsFunctio
   /* FIXME: figure out what to do in these situations */
   if (frame == NULL)
     return;
-  if (thisp && frame->thisp == NULL)
+  /* second check especially for super object */
+  if (thisp != NULL && frame->thisp == NULL)
     swfdec_as_frame_set_this (frame, thisp);
   frame->is_local = TRUE;
   frame->argc = n_args;
@@ -99,6 +100,25 @@ swfdec_as_function_call (SwfdecAsFunctio
 
 /*** AS CODE ***/
 
+static void
+swfdec_as_function_do_call (SwfdecAsContext *context, SwfdecAsObject *fun,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+  SwfdecAsObject *thisp;
+
+  if (argc > 0) {
+    thisp = swfdec_as_value_to_object (context, &argv[0]);
+    argc -= 1;
+    argv++;
+  } else {
+    thisp = NULL;
+  }
+  if (thisp == NULL)
+    thisp = swfdec_as_object_new_empty (context);
+  swfdec_as_function_call (SWFDEC_AS_FUNCTION (fun), thisp, argc, argv, ret);
+  swfdec_as_context_run (context);
+}
+
 void
 swfdec_as_function_init_context (SwfdecAsContext *context, guint version)
 {
@@ -126,6 +146,9 @@ swfdec_as_function_init_context (SwfdecA
     SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
     swfdec_as_object_set_variable (function, SWFDEC_AS_STR___proto__, &val);
     swfdec_as_object_set_variable (function, SWFDEC_AS_STR_prototype, &val);
+    /* prototype functions */
+    swfdec_as_object_add_function (proto, SWFDEC_AS_STR_call, SWFDEC_TYPE_AS_FUNCTION, 
+	swfdec_as_function_do_call, 0);
   }
 }
 
diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index f7d3d6b..ee9089a 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -222,6 +222,7 @@ const char swfdec_as_strings[] = 
   SWFDEC_AS_CONSTANT_STRING ("bytesLoaded")
   SWFDEC_AS_CONSTANT_STRING ("bytesTotal")
   SWFDEC_AS_CONSTANT_STRING ("indexOf")
+  SWFDEC_AS_CONSTANT_STRING ("call")
   /* add more here */
 ;
 
diff-tree 14343adf3d551aec7aad37ddcbd5170499d14957 (from 5cc853b363b92b32789a3de52363c0577a6a0cce)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 15:09:00 2007 +0100

    add swfdec_as_object_new_empty for getting a raw object
    
    This object will not have __constructor__ or __proto__ set

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 022b44c..a8d1454 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -460,7 +460,7 @@ swfdec_as_context_init (SwfdecAsContext 
     g_hash_table_insert (context->strings, (char *) s + 1, (char *) s);
   }
   g_assert (*s == 0);
-  context->global = swfdec_as_object_new (context);
+  context->global = swfdec_as_object_new_empty (context);
   context->rand = g_rand_new ();
   g_get_current_time (&context->start_time);
 }
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 48e71b3..22e65b1 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -119,7 +119,7 @@ swfdec_as_function_init_context (SwfdecA
   SWFDEC_AS_VALUE_SET_OBJECT (&val, function);
   swfdec_as_object_set_variable (function, SWFDEC_AS_STR_constructor, &val);
   if (version > 5) {
-    proto = swfdec_as_object_new (context);
+    proto = swfdec_as_object_new_empty (context);
     if (!proto)
       return;
     context->Function_prototype = proto;
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 0ffeed3..087e47d 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -222,6 +222,20 @@ swfdec_as_object_init (SwfdecAsObject *o
 {
 }
 
+SwfdecAsObject *
+swfdec_as_object_new_empty (SwfdecAsContext *context)
+{
+  SwfdecAsObject *object;
+
+  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));
+  return object;
+}
+
 /**
  * swfdec_as_object_new:
  * @context: a #SwfdecAsContext
@@ -236,21 +250,17 @@ SwfdecAsObject *
 swfdec_as_object_new (SwfdecAsContext *context)
 {
   SwfdecAsObject *object;
+  SwfdecAsValue val;
 
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
+  g_assert (context->Object);
+  g_assert (context->Object_prototype);
   
-  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));
-  if (context->Object) {
-    SwfdecAsValue val;
-    g_assert (context->Object_prototype);
-    SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
-    swfdec_as_object_set_variable (object, SWFDEC_AS_STR___proto__, &val);
-    SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object);
-    swfdec_as_object_set_variable (object, SWFDEC_AS_STR_constructor, &val);
-  }
+  object = swfdec_as_object_new_empty (context);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object_prototype);
+  swfdec_as_object_set_variable (object, SWFDEC_AS_STR___proto__, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Object);
+  swfdec_as_object_set_variable (object, SWFDEC_AS_STR_constructor, &val);
   return object;
 }
 
@@ -685,7 +695,7 @@ swfdec_as_object_init_context (SwfdecAsC
       SWFDEC_AS_STR_Object, 0, NULL, 0));
   if (!object)
     return;
-  proto = swfdec_as_object_new (context);
+  proto = swfdec_as_object_new_empty (context);
   if (!proto)
     return;
   context->Object = object;
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 73f28e2..953e5fb 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -93,6 +93,7 @@ struct _SwfdecAsObjectClass {
 GType		swfdec_as_object_get_type	(void);
 
 SwfdecAsObject *swfdec_as_object_new		(SwfdecAsContext *    	context);
+SwfdecAsObject *swfdec_as_object_new_empty    	(SwfdecAsContext *    	context);
 SwfdecAsObject *swfdec_as_object_create		(SwfdecAsFunction *	construct,
 						 guint			n_args,
 						 const SwfdecAsValue *	args,
diff-tree 5cc853b363b92b32789a3de52363c0577a6a0cce (from 4964db79fca7d6c9f88c75a848a67a73eb33f405)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 14:02:24 2007 +0100

    improve test - we want to be really sure this is undefined
    
    It could've been that it just evaluates to the string "undefined" when printed.

diff --git a/test/trace/callmethod-undefined-this-5.swf b/test/trace/callmethod-undefined-this-5.swf
index 0f47114..cbe53b0 100644
Binary files a/test/trace/callmethod-undefined-this-5.swf and b/test/trace/callmethod-undefined-this-5.swf differ
diff --git a/test/trace/callmethod-undefined-this-5.swf.trace b/test/trace/callmethod-undefined-this-5.swf.trace
index 08ee0cc..76685bd 100644
--- a/test/trace/callmethod-undefined-this-5.swf.trace
+++ b/test/trace/callmethod-undefined-this-5.swf.trace
@@ -3,3 +3,5 @@ undefined
 undefined
 undefined
 undefined
+undefined
+undefined
diff --git a/test/trace/callmethod-undefined-this-6.swf b/test/trace/callmethod-undefined-this-6.swf
index d410eea..66555b5 100644
Binary files a/test/trace/callmethod-undefined-this-6.swf and b/test/trace/callmethod-undefined-this-6.swf differ
diff --git a/test/trace/callmethod-undefined-this-6.swf.trace b/test/trace/callmethod-undefined-this-6.swf.trace
index 08ee0cc..76685bd 100644
--- a/test/trace/callmethod-undefined-this-6.swf.trace
+++ b/test/trace/callmethod-undefined-this-6.swf.trace
@@ -3,3 +3,5 @@ undefined
 undefined
 undefined
 undefined
+undefined
+undefined
diff --git a/test/trace/callmethod-undefined-this-7.swf b/test/trace/callmethod-undefined-this-7.swf
index 3fa58b4..485cdea 100644
Binary files a/test/trace/callmethod-undefined-this-7.swf and b/test/trace/callmethod-undefined-this-7.swf differ
diff --git a/test/trace/callmethod-undefined-this-7.swf.trace b/test/trace/callmethod-undefined-this-7.swf.trace
index 08ee0cc..76685bd 100644
--- a/test/trace/callmethod-undefined-this-7.swf.trace
+++ b/test/trace/callmethod-undefined-this-7.swf.trace
@@ -3,3 +3,5 @@ undefined
 undefined
 undefined
 undefined
+undefined
+undefined
diff --git a/test/trace/callmethod-undefined-this.as b/test/trace/callmethod-undefined-this.as
index b4d7c01..441bbc5 100644
--- a/test/trace/callmethod-undefined-this.as
+++ b/test/trace/callmethod-undefined-this.as
@@ -3,6 +3,8 @@
 trace ("Test the behaviour of CallMethod with a function name of undefined or \"\"");
 function foo () {
   trace (this);
+  this.x = 15;
+  trace (this.x);
   return this;
 };
 asm {
diff-tree 4964db79fca7d6c9f88c75a848a67a73eb33f405 (from 8b05ebd0dcff60cbe8c046dc4cbd2905b9dd5619)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 00:09:35 2007 +0100

    prototypes created with ActionExtends don't get a constuctor property

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index cc36c7e..54347c7 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1840,7 +1840,7 @@ swfdec_action_extends (SwfdecAsContext *
 {
   SwfdecAsValue *superclass, *subclass, proto;
   SwfdecAsObject *prototype;
-  SwfdecAsFunction *super;
+  SwfdecAsObject *super;
 
   superclass = swfdec_as_stack_pop (cx->frame->stack);
   subclass = swfdec_as_stack_pop (cx->frame->stack);
@@ -1853,13 +1853,13 @@ swfdec_action_extends (SwfdecAsContext *
     SWFDEC_ERROR ("subclass is not an object");
     return;
   }
-  super = SWFDEC_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (superclass));
+  super = SWFDEC_AS_VALUE_GET_OBJECT (superclass);
   prototype = swfdec_as_object_new (cx);
   if (prototype == NULL)
     return;
-  swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (super),
-      SWFDEC_AS_STR_prototype, &proto);
+  swfdec_as_object_get_variable (super, SWFDEC_AS_STR_prototype, &proto);
   swfdec_as_object_set_variable (prototype, SWFDEC_AS_STR___proto__, &proto);
+  swfdec_as_object_delete_variable (prototype, SWFDEC_AS_STR_constructor);
   swfdec_as_object_set_variable (prototype, SWFDEC_AS_STR___constructor__,
       superclass);
   SWFDEC_AS_VALUE_SET_OBJECT (&proto, prototype);
diff-tree 8b05ebd0dcff60cbe8c046dc4cbd2905b9dd5619 (from 9777071e57bc154ef6a1bb0c166125be7669ccbd)
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Jul 4 00:08:11 2007 +0100

    fix Object.hasOwnProperty() to only look at the current object

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 1fc8cf0..0ffeed3 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -642,12 +642,15 @@ static void
 swfdec_as_object_hasOwnProperty (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
 {
+  SwfdecAsObjectClass *klass;
   const char *name;
   guint flags;
+  SwfdecAsValue value;
 
   name = swfdec_as_value_to_string (object->context, &argv[0]);
   
-  if (swfdec_as_object_get_variable_and_flags (object, name, NULL, &flags) &&
+  klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
+  if (klass->get (object, name, &value, &flags) &&
       (flags & SWFDEC_AS_VARIABLE_NATIVE) == 0)
     SWFDEC_AS_VALUE_SET_BOOLEAN (retval, TRUE);
   else
diff-tree 9777071e57bc154ef6a1bb0c166125be7669ccbd (from e362e2a248b0fb532b28ebfa8b9322e2ac01809d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 23:58:49 2007 +0100

    reimplement enumerate

diff --git a/player/swfdec_player_manager.c b/player/swfdec_player_manager.c
index 966c170..1a838bd 100644
--- a/player/swfdec_player_manager.c
+++ b/player/swfdec_player_manager.c
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <libswfdec/swfdec_debugger.h>
+#include <libswfdec/swfdec_as_object.h>
 #include "swfdec_player_manager.h"
 #include <libswfdec-gtk/swfdec_source.h>
 
@@ -563,49 +564,38 @@ command_find (SwfdecPlayerManager *manag
   swfdec_debugger_foreach_script (SWFDEC_DEBUGGER (manager->player), do_find, &data);
 }
 
-#if 0
+static gboolean
+enumerate_foreach (SwfdecAsObject *object, const char *variable, 
+    SwfdecAsValue *value, guint flags, gpointer manager)
+{
+  char *s;
+
+  s = swfdec_as_value_to_debug (value);
+  swfdec_player_manager_output (manager, "  %s: %s", variable, s);
+  g_free (s);
+  
+  return TRUE;
+}
+
 static void
 command_enumerate (SwfdecPlayerManager *manager, const char *arg)
 {
-  jsval rval;
-  JSObject *obj;
-  JSIdArray *array;
-  const char *s, *t;
-  guint i;
+  SwfdecAsValue val;
+  char *s;
+  SwfdecAsObject *object;
 
-  if (!swfdec_js_run (manager->player, arg, &rval)) {
-    swfdec_player_manager_error (manager, "Invalid command");
-    return;
-  }
-  if (!JSVAL_IS_OBJECT (rval)) {
-    swfdec_player_manager_error (manager, "Given expression is not an object");
+  if (arg == NULL)
     return;
-  }
-  obj = JSVAL_TO_OBJECT (rval);
-  array = JS_Enumerate (manager->player->jscx, obj);
-  if (array == NULL) {
-    swfdec_player_manager_error (manager, "Error enumerating");
+
+  swfdec_as_context_eval (SWFDEC_AS_CONTEXT (manager->player), NULL, arg, &val);
+  s = swfdec_as_value_to_debug (&val);
+  swfdec_player_manager_output (manager, "%s", s);
+  g_free (s);
+  if (!SWFDEC_AS_VALUE_IS_OBJECT (&val))
     return;
-  }
-  s = swfdec_js_to_string (manager->player->jscx, rval);
-  if (s == NULL) {
-    swfdec_player_manager_error (manager, "Cannot convert object to string");
-  }
-  swfdec_player_manager_output (manager, "properties for %s:", s);
-  for (i = 0; i < array->length; i++) {
-    if (!JS_IdToValue (manager->player->jscx, array->vector[i], &rval))
-      continue;
-    s = swfdec_js_to_string (manager->player->jscx, rval);
-    if (s == NULL)
-      continue;
-    if (!JS_GetProperty (manager->player->jscx, obj, s, &rval) ||
-	!(t = swfdec_js_to_string (manager->player->jscx, rval)))
-      t = "<error querying value>";
-    swfdec_player_manager_output (manager, "  %s: %s", s, t);
-  }
-  JS_DestroyIdArray (manager->player->jscx, array);
+  object = SWFDEC_AS_VALUE_GET_OBJECT (&val);
+  swfdec_as_object_foreach (object, enumerate_foreach, manager);
 }
-#endif
 
 static void command_help (SwfdecPlayerManager *manager, const char *arg);
 /* NB: the first word in the command string is used, partial matches are ok */
@@ -625,9 +615,7 @@ struct {
   { "continue",	command_continue,	"continue when stopped inside a breakpoint" },
   { "next",	command_next,		"step forward one command when stopped inside a breakpoint" },
   { "find",	command_find,		"find the given argument verbatim in all scripts" },
-#if 0
   { "enumerate",command_enumerate,    	"enumerate all properties of the given object" },
-#endif
 };
 
 static void
diff-tree e362e2a248b0fb532b28ebfa8b9322e2ac01809d (from acab3ebdd8fc365500c9ae83f3f3f34787433a8d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 23:57:47 2007 +0100

    implement debug functions

diff --git a/libswfdec/swfdec_as_native_function.c b/libswfdec/swfdec_as_native_function.c
index 87f937d..a7554c1 100644
--- a/libswfdec/swfdec_as_native_function.c
+++ b/libswfdec/swfdec_as_native_function.c
@@ -59,6 +59,14 @@ swfdec_as_native_function_call (SwfdecAs
   return frame;
 }
 
+static char *
+swfdec_as_native_function_debug (SwfdecAsObject *object)
+{
+  SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (object);
+
+  return g_strdup_printf ("%s ()", native->name);
+}
+
 static void
 swfdec_as_native_function_dispose (GObject *object)
 {
@@ -74,10 +82,13 @@ static void
 swfdec_as_native_function_class_init (SwfdecAsNativeFunctionClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  SwfdecAsObjectClass *asobject_class = SWFDEC_AS_OBJECT_CLASS (klass);
   SwfdecAsFunctionClass *function_class = SWFDEC_AS_FUNCTION_CLASS (klass);
 
   object_class->dispose = swfdec_as_native_function_dispose;
 
+  asobject_class->debug = swfdec_as_native_function_debug;
+
   function_class->call = swfdec_as_native_function_call;
 }
 
diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index 78bf52d..eff76b2 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -62,7 +62,7 @@ swfdec_as_script_function_dispose (GObje
 static void
 swfdec_as_script_function_mark (SwfdecAsObject *object)
 {
-  SwfdecAsScriptFunction *script= SWFDEC_AS_SCRIPT_FUNCTION (object);
+  SwfdecAsScriptFunction *script = SWFDEC_AS_SCRIPT_FUNCTION (object);
 
   if (script->scope)
     swfdec_as_object_mark (SWFDEC_AS_OBJECT (script->scope));
@@ -70,6 +70,26 @@ swfdec_as_script_function_mark (SwfdecAs
   SWFDEC_AS_OBJECT_CLASS (swfdec_as_script_function_parent_class)->mark (object);
 }
 
+static char *
+swfdec_as_script_function_debug (SwfdecAsObject *object)
+{
+  SwfdecAsScriptFunction *script = SWFDEC_AS_SCRIPT_FUNCTION (object);
+  SwfdecScript *s = script->script;
+  GString *string;
+  guint i;
+
+  string = g_string_new (s->name);
+  g_string_append (string, " (");
+  for (i = 0; i < s->n_arguments; i++) {
+    if (i > 0)
+      g_string_append (string, ", ");
+    g_string_append (string, s->arguments[i].name);
+  }
+  g_string_append (string, ")");
+
+  return g_string_free (string, FALSE);
+}
+
 static void
 swfdec_as_script_function_class_init (SwfdecAsScriptFunctionClass *klass)
 {
@@ -80,6 +100,7 @@ swfdec_as_script_function_class_init (Sw
   object_class->dispose = swfdec_as_script_function_dispose;
 
   asobject_class->mark = swfdec_as_script_function_mark;
+  asobject_class->debug = swfdec_as_script_function_debug;
 
   function_class->call = swfdec_as_script_function_call;
 }
diff-tree acab3ebdd8fc365500c9ae83f3f3f34787433a8d (from 5e272397358c36cb5a88da6824dd8ce0f1b2d80d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 18:10:48 2007 +0100

    add functions for debugging objects and use them

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index e3bd49e..1fc8cf0 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -191,6 +191,15 @@ swfdec_as_object_do_foreach (SwfdecAsObj
   return fdata.retval;
 }
 
+static char *
+swfdec_as_object_do_debug (SwfdecAsObject *object)
+{
+  if (G_OBJECT_TYPE (object) != SWFDEC_TYPE_AS_OBJECT)
+    return g_strdup (G_OBJECT_TYPE_NAME (object));
+
+  return g_strdup ("Object");
+}
+
 static void
 swfdec_as_object_class_init (SwfdecAsObjectClass *klass)
 {
@@ -205,6 +214,7 @@ swfdec_as_object_class_init (SwfdecAsObj
   klass->set_flags = swfdec_as_object_do_set_flags;
   klass->delete = swfdec_as_object_do_delete;
   klass->foreach = swfdec_as_object_do_foreach;
+  klass->debug = swfdec_as_object_do_debug;
 }
 
 static void
@@ -706,3 +716,14 @@ swfdec_as_variable_set (SwfdecAsVariable
   var->value = *value;
 }
 
+char *
+swfdec_as_object_get_debug (SwfdecAsObject *object)
+{
+  SwfdecAsObjectClass *klass;
+
+  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (object), NULL);
+
+  klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
+  return klass->debug (object);
+}
+
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 8a51021..73f28e2 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -87,6 +87,7 @@ struct _SwfdecAsObjectClass {
   gboolean		(* foreach)		(SwfdecAsObject *	object,
 						 SwfdecAsVariableForeach func,
 						 gpointer		data);
+  char *		(* debug)		(SwfdecAsObject *	object);
 };
 
 GType		swfdec_as_object_get_type	(void);
@@ -99,6 +100,7 @@ SwfdecAsObject *swfdec_as_object_create	
 void		swfdec_as_object_set_constructor(SwfdecAsObject *	object,
 						 SwfdecAsObject *	construct,
 						 gboolean		scripted);
+char *		swfdec_as_object_get_debug	(SwfdecAsObject *	object);
 
 void		swfdec_as_object_add		(SwfdecAsObject *     	object,
 						 SwfdecAsContext *    	context,
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 097260e..38a636f 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -390,6 +390,39 @@ swfdec_as_value_to_string (SwfdecAsConte
 }
 
 /**
+ * swfdec_as_value_to_debug:
+ * @value: a #SwfdecAsValue
+ *
+ * Converts the given @value to a string in a safe way. It will not call into
+ * the scripting engine. Its intended use is for output in debuggers.
+ *
+ * Returns: a newly allocated string. Free with g_free().
+ **/
+char *
+swfdec_as_value_to_debug (const SwfdecAsValue *value)
+{
+  g_return_val_if_fail (SWFDEC_IS_AS_VALUE (value), NULL);
+
+  switch (value->type) {
+    case SWFDEC_AS_TYPE_STRING:
+      return g_strdup (SWFDEC_AS_VALUE_GET_STRING (value));
+    case SWFDEC_AS_TYPE_UNDEFINED:
+      return g_strdup ("undefined");
+    case SWFDEC_AS_TYPE_BOOLEAN:
+      return g_strdup (SWFDEC_AS_VALUE_GET_BOOLEAN (value) ? "true" : "false");
+    case SWFDEC_AS_TYPE_NULL:
+      return g_strdup ("null");
+    case SWFDEC_AS_TYPE_NUMBER:
+      return g_strdup_printf ("%g", SWFDEC_AS_VALUE_GET_NUMBER (value));
+    case SWFDEC_AS_TYPE_OBJECT:
+      return swfdec_as_object_get_debug (SWFDEC_AS_VALUE_GET_OBJECT (value));
+    default:
+      g_assert_not_reached ();
+      return NULL;
+  }
+}
+
+/**
  * swfdec_as_value_to_number:
  * @context: a #SwfdecAsContext
  * @value: a #SwfdecAsValue used by context
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index a44d041..51bc65e 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -221,6 +221,7 @@ SwfdecAsObject *swfdec_as_value_to_objec
 void		swfdec_as_value_to_primitive	(SwfdecAsValue *	value);
 const char *	swfdec_as_value_to_string	(SwfdecAsContext *	context,
 						 const SwfdecAsValue *	value);
+char *		swfdec_as_value_to_debug	(const SwfdecAsValue *	value);
 
 /* special conversion functions */
 const char *	swfdec_as_double_to_string	(SwfdecAsContext *	context,
diff --git a/player/swfdec_debug_stack.c b/player/swfdec_debug_stack.c
index b6f2a91..3afffea 100644
--- a/player/swfdec_debug_stack.c
+++ b/player/swfdec_debug_stack.c
@@ -72,11 +72,12 @@ swfdec_debug_stack_set_model (SwfdecDebu
     guint i = 0;
     for (val = frame->stack->cur - 1; val >= frame->stack->base; val--) {
       /* FIXME: dangerous, this calls back into the engine */
-      const char *s = swfdec_as_value_to_string (SWFDEC_AS_CONTEXT (debug->manager->player), val);
+      char *s = swfdec_as_value_to_debug (val);
       gtk_list_store_append (store, &iter);
       gtk_list_store_set (store, &iter, COLUMN_LINE, ++i, 
 	COLUMN_TYPE, swfdec_get_value_type (SWFDEC_AS_CONTEXT (debug->manager->player), val),
 	COLUMN_CONTENT, s, -1);
+      g_free (s);
     }
   }
 
diff-tree 5e272397358c36cb5a88da6824dd8ce0f1b2d80d (from 66fd508e7b615605b416c4bf66c7c39942e2e97b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 17:35:53 2007 +0100

    reuse the existing variable

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index cb4512c..4dc861c 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -403,7 +403,7 @@ swfdec_as_frame_preload (SwfdecAsFrame *
       if (i < frame->argc) {
 	swfdec_as_object_set_variable (object, tmp, &frame->argv[i]);
       } else {
-	SwfdecAsValue val = { 0, };
+	SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
 	swfdec_as_object_set_variable (object, tmp, &val);
       }
     }
diff-tree 66fd508e7b615605b416c4bf66c7c39942e2e97b (from dc1dd7c46001164169452e2bf7e2d57f2b87d7d9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 17:08:37 2007 +0100

    only set thisp if it isn't set yet
    
    Stupid workaround for super, which sets the this object itself

diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index 9465ebc..48e71b3 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -88,7 +88,7 @@ swfdec_as_function_call (SwfdecAsFunctio
   /* FIXME: figure out what to do in these situations */
   if (frame == NULL)
     return;
-  if (thisp)
+  if (thisp && frame->thisp == NULL)
     swfdec_as_frame_set_this (frame, thisp);
   frame->is_local = TRUE;
   frame->argc = n_args;
diff-tree dc1dd7c46001164169452e2bf7e2d57f2b87d7d9 (from 5f658c3c6e686d46bb9d67f4d633a2403d8dbd8a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 17:08:08 2007 +0100

    really set super here

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index a5718bd..cb4512c 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -361,6 +361,7 @@ swfdec_as_frame_preload (SwfdecAsFrame *
       if (script->flags & SWFDEC_SCRIPT_PRELOAD_SUPER) {
 	SWFDEC_AS_VALUE_SET_OBJECT (&frame->registers[current_reg++], super);
       } else {
+	SWFDEC_AS_VALUE_SET_OBJECT (&val, super);
 	swfdec_as_object_set_variable (object, SWFDEC_AS_STR_super, &val);
       }
     }
diff-tree 5f658c3c6e686d46bb9d67f4d633a2403d8dbd8a (from 2cab942175d4b73aedd4d787a75a36ef42d4b535)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 15:08:46 2007 +0100

    add ugly workaround for sound code

diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 5a110a9..5c40d39 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -501,6 +501,10 @@ swfdec_sprite_movie_iterate_end (SwfdecM
   if (movie->sprite == NULL)
     return TRUE;
   g_assert (movie->frame <= movie->n_frames);
+  if (movie->frame == 0) {
+    SWFDEC_WARNING ("not at first frame yet");
+    return TRUE;
+  }
   current = &movie->sprite->frames[movie->frame - 1];
   /* first start all event sounds */
   /* FIXME: is this correct? */
diff-tree 2cab942175d4b73aedd4d787a75a36ef42d4b535 (from da901547bba31c89211257b02db25e2d71a28505)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 15:08:28 2007 +0100

    if the object isn't a movie, TargetPath returns undefined

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index f709b6e..cc36c7e 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1652,7 +1652,7 @@ swfdec_action_target_path (SwfdecAsConte
   if (!SWFDEC_AS_VALUE_IS_OBJECT (val) ||
       !SWFDEC_IS_MOVIE (movie = (SwfdecMovie *) SWFDEC_AS_VALUE_GET_OBJECT (val))) {
     SWFDEC_FIXME ("What's the TargetPath for non-movies?");
-    SWFDEC_AS_VALUE_SET_STRING (val, SWFDEC_AS_STR_EMPTY);
+    SWFDEC_AS_VALUE_SET_UNDEFINED (val);
     return;
   }
   s = swfdec_movie_get_path (movie);
diff-tree da901547bba31c89211257b02db25e2d71a28505 (from 71cdae101afa3ffbc34bc4790ffbc9d435c9d8c3)
Author: Benjamin Otte <otte at gnome.org>
Date:   Tue Jul 3 15:07:54 2007 +0100

    revert earlier commit - it wasn't buggy
    
    adding to the context doesn't happen in initialize.
    The code used to crash because the movie wasn't added at all since
    the context had aborted. That has been fixed.

diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 0ae840f..98d0619 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -1007,12 +1007,12 @@ swfdec_movie_new_for_content (SwfdecMovi
   swfdec_movie_set_static_properties (movie, content->has_transform ? &content->transform : NULL,
       content->has_color_transform ? &content->color_transform : NULL, 
       content->ratio, content->clip_depth, content->events);
+  swfdec_movie_initialize (movie);
   if (SWFDEC_IS_SPRITE_MOVIE (movie)) {
     g_queue_push_tail (player->init_queue, movie);
     g_queue_push_tail (player->construct_queue, movie);
     swfdec_movie_queue_script (movie, SWFDEC_EVENT_LOAD);
   }
-  swfdec_movie_initialize (movie);
 
   return movie;
 }


More information about the Swfdec mailing list