[Swfdec] Branch 'as' - 24 commits - configure.ac doc/Makefile.am doc/swfdec-sections.txt libswfdec/Makefile.am libswfdec/swfdec_amf.c libswfdec/swfdec_as_array.c 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_math.c libswfdec/swfdec_as_native_function.c libswfdec/swfdec_as_number.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_script_function.c libswfdec/swfdec_as_stack.c libswfdec/swfdec_as_stack.h libswfdec/swfdec_as_string.c libswfdec/swfdec_as_super.c libswfdec/swfdec_as_types.c libswfdec/swfdec_as_types.h libswfdec/swfdec_button_movie.c libswfdec/swfdec_color_as.c libswfdec/swfdec_edittext_movie.c libswfdec/swfdec_event.c libswfdec/swfdec.h libswfdec/swfdec_mouse_as.c libswfdec/swfdec_movie_asprops.c libswfdec/swfdec_movie.c libswfdec/swfdec_net_connection.c libswfdec/swfdec_net_stream_as.c libswfdec/swfdec_net_stream.c libswfdec/swfdec_player_as.c libswfdec/swfdec_player.c libswfdec/swfdec_sprite_movie_as.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_video_movie_as.c libswfdec/swfdec_xml_as.c libswfdec/swfdec_xml.c test/trace

Benjamin Otte company at kemper.freedesktop.org
Mon Jul 2 03:21:12 PDT 2007


 configure.ac                               |    6 
 doc/Makefile.am                            |    1 
 doc/swfdec-sections.txt                    |   21 --
 libswfdec/Makefile.am                      |    4 
 libswfdec/swfdec.h                         |    3 
 libswfdec/swfdec_amf.c                     |    8 
 libswfdec/swfdec_as_array.c                |   15 -
 libswfdec/swfdec_as_context.c              |  117 +++++++++----
 libswfdec/swfdec_as_context.h              |    8 
 libswfdec/swfdec_as_frame.c                |   34 +++
 libswfdec/swfdec_as_frame.h                |    2 
 libswfdec/swfdec_as_function.c             |    4 
 libswfdec/swfdec_as_interpret.c            |   13 -
 libswfdec/swfdec_as_math.c                 |    1 
 libswfdec/swfdec_as_native_function.c      |    2 
 libswfdec/swfdec_as_number.c               |    3 
 libswfdec/swfdec_as_object.c               |   23 --
 libswfdec/swfdec_as_object.h               |    2 
 libswfdec/swfdec_as_script_function.c      |    3 
 libswfdec/swfdec_as_stack.c                |    2 
 libswfdec/swfdec_as_stack.h                |    2 
 libswfdec/swfdec_as_string.c               |    1 
 libswfdec/swfdec_as_super.c                |    3 
 libswfdec/swfdec_as_types.c                |    1 
 libswfdec/swfdec_as_types.h                |    2 
 libswfdec/swfdec_button_movie.c            |    1 
 libswfdec/swfdec_color_as.c                |    1 
 libswfdec/swfdec_edittext_movie.c          |    1 
 libswfdec/swfdec_event.c                   |    1 
 libswfdec/swfdec_mouse_as.c                |    1 
 libswfdec/swfdec_movie.c                   |    1 
 libswfdec/swfdec_movie_asprops.c           |    1 
 libswfdec/swfdec_net_connection.c          |    3 
 libswfdec/swfdec_net_stream.c              |    1 
 libswfdec/swfdec_net_stream_as.c           |    1 
 libswfdec/swfdec_player.c                  |    1 
 libswfdec/swfdec_player_as.c               |    1 
 libswfdec/swfdec_sprite_movie.c            |    1 
 libswfdec/swfdec_sprite_movie_as.c         |    1 
 libswfdec/swfdec_video_movie_as.c          |    1 
 libswfdec/swfdec_xml.c                     |    1 
 libswfdec/swfdec_xml_as.c                  |    1 
 test/trace/Makefile.am                     |   18 +-
 test/trace/abort-really-aborts-5.swf       |binary
 test/trace/abort-really-aborts-5.swf.trace |    1 
 test/trace/abort-really-aborts-6.swf       |binary
 test/trace/abort-really-aborts-6.swf.trace |    1 
 test/trace/abort-really-aborts-7.swf       |binary
 test/trace/abort-really-aborts-7.swf.trace |    1 
 test/trace/abort-really-aborts.as          |   13 +
 test/trace/stack-overflow-5.swf            |binary
 test/trace/stack-overflow-5.swf.trace      |  256 +++++++++++++++++++++++++++++
 test/trace/stack-overflow-6.swf            |binary
 test/trace/stack-overflow-6.swf.trace      |  256 +++++++++++++++++++++++++++++
 test/trace/stack-overflow-7.swf            |binary
 test/trace/stack-overflow-7.swf.trace      |  256 +++++++++++++++++++++++++++++
 test/trace/stack-overflow.as               |   13 +
 test/trace/trace.c                         |  191 +++++++++++++++++----
 58 files changed, 1149 insertions(+), 157 deletions(-)

New commits:
diff-tree 6e58faa8ad4c043914e9a838a39c607dd578d107 (from 1f718a32a857b2ea082f6a4b3dafb06bb81d7aa1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 10:07:12 2007 +0100

    swfdec_as_stack_ensure_left => swfdec_as_stack_ensure_free
    
    The old name was confusing. I never knew if the function checked the number of
    slots the were occupied, or the ones that were not.

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 53884ba..022b44c 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -687,10 +687,10 @@ start:
     if (spec->remove > 0) {
       swfdec_as_stack_ensure_size (stack, spec->remove);
       if (spec->add > spec->remove)
-	swfdec_as_stack_ensure_left (stack, spec->add - spec->remove);
+	swfdec_as_stack_ensure_free (stack, spec->add - spec->remove);
     } else {
       if (spec->add > 0)
-	swfdec_as_stack_ensure_left (stack, spec->add);
+	swfdec_as_stack_ensure_free (stack, spec->add);
     }
     if (context->state != SWFDEC_AS_CONTEXT_RUNNING)
       goto error;
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 3195a8c..649ec36 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -321,7 +321,7 @@ swfdec_action_push (SwfdecAsContext *cx,
   while (swfdec_bits_left (&bits)) {
     guint type = swfdec_bits_get_u8 (&bits);
     SWFDEC_LOG ("push type %u", type);
-    swfdec_as_stack_ensure_left (stack, 1);
+    swfdec_as_stack_ensure_free (stack, 1);
     switch (type) {
       case 0: /* string */
 	{
@@ -1553,7 +1553,7 @@ swfdec_action_define_function (SwfdecAsC
   swfdec_script_add_to_context (script, cx);
   /* attach the function */
   if (*function_name == '\0') {
-    swfdec_as_stack_ensure_left (frame->stack, 1);
+    swfdec_as_stack_ensure_free (frame->stack, 1);
     SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_push (frame->stack), SWFDEC_AS_OBJECT (fun));
   } else {
     SwfdecAsValue funval;
@@ -1863,7 +1863,7 @@ swfdec_action_do_enumerate (SwfdecAsObje
 
   if (flags & SWFDEC_AS_VARIABLE_DONT_ENUM)
     return TRUE;
-  swfdec_as_stack_ensure_left (stack, 1);
+  swfdec_as_stack_ensure_free (stack, 1);
   SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_push (stack), variable);
   return TRUE;
 }
diff --git a/libswfdec/swfdec_as_stack.c b/libswfdec/swfdec_as_stack.c
index 0354b49..2b9f678 100644
--- a/libswfdec/swfdec_as_stack.c
+++ b/libswfdec/swfdec_as_stack.c
@@ -88,7 +88,7 @@ swfdec_as_stack_ensure_size (SwfdecAsSta
 }
 
 void
-swfdec_as_stack_ensure_left (SwfdecAsStack *stack, guint n_elements)
+swfdec_as_stack_ensure_free (SwfdecAsStack *stack, guint n_elements)
 {
   g_return_if_fail (stack != NULL);
 
diff --git a/libswfdec/swfdec_as_stack.h b/libswfdec/swfdec_as_stack.h
index a415406..ec25a71 100644
--- a/libswfdec/swfdec_as_stack.h
+++ b/libswfdec/swfdec_as_stack.h
@@ -88,7 +88,7 @@ swfdec_as_stack_push (SwfdecAsStack *sta
 void		swfdec_as_stack_mark		(SwfdecAsStack *	stack);
 void		swfdec_as_stack_ensure_size	(SwfdecAsStack *	stack,
 						 guint	  		n_elements);
-void		swfdec_as_stack_ensure_left	(SwfdecAsStack *	stack,
+void		swfdec_as_stack_ensure_free	(SwfdecAsStack *	stack,
 						 guint	  		n_elements);
 						
 
diff-tree 1f718a32a857b2ea082f6a4b3dafb06bb81d7aa1 (from 7fbf55d8d94b107b925e356a656362bd0e4b9159)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 10:02:19 2007 +0100

    get rid of the enum get_type() functions

diff --git a/doc/Makefile.am b/doc/Makefile.am
index ce3ae3a..3749a2c 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -81,6 +81,7 @@ IGNORE_HFILES= \
 	swfdec_decoder.h \
 	swfdec_edittext.h \
 	swfdec_edittext_movie.h \
+	swfdec_enums.h \
 	swfdec_event.h \
 	swfdec_flv_decoder.h \
 	swfdec_font.h \
diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index 70e8128..b88f06e 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -105,11 +105,6 @@ swfdec_buffer_queue_get_type
 SwfdecLoaderDataType
 swfdec_loader_data_type_get_extension
 SwfdecMouseCursor
-<SUBSECTION Standard>
-SWFDEC_TYPE_LOADER_DATA_TYPE
-swfdec_loader_data_type_get_type
-SWFDEC_TYPE_MOUSE_CURSOR
-swfdec_mouse_cursor_get_type
 </SECTION>
 
 
@@ -224,21 +219,18 @@ SWFDEC_AS_VALUE_IS_OBJECT
 <SECTION>
 <FILE>SwfdecAsContext</FILE>
 <TITLE>SwfdecAsContext</TITLE>
+swfdec_as_context_startup
 swfdec_as_context_abort
-swfdec_as_context_abort_oom
-swfdec_as_context_eval
-swfdec_as_context_eval_set
-swfdec_as_context_gc
 swfdec_as_context_get_string
-swfdec_as_context_get_time
 swfdec_as_context_give_string
+swfdec_as_context_use_mem
+swfdec_as_context_gc
 swfdec_as_context_maybe_gc
-swfdec_as_context_new
-swfdec_as_context_return
 swfdec_as_context_run
-swfdec_as_context_startup
 swfdec_as_context_unuse_mem
-swfdec_as_context_use_mem
+swfdec_as_context_eval
+swfdec_as_context_eval_set
+swfdec_as_context_get_time
 <SUBSECTION Standard>
 swfdec_as_context_get_type
 SwfdecAsContextClass
diff-tree 7fbf55d8d94b107b925e356a656362bd0e4b9159 (from fe60ff709e503e0efd1e5d025f8fdb1c91052331)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:56:53 2007 +0100

    include swfec_as_strings.h here, too

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index a79fc66..53884ba 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -34,6 +34,7 @@
 #include "swfdec_as_object.h"
 #include "swfdec_as_stack.h"
 #include "swfdec_as_string.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_as_types.h"
 #include "swfdec_debug.h"
 #include "swfdec_script.h"
diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 504245d..097260e 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -29,6 +29,7 @@
 #include "swfdec_as_context.h"
 #include "swfdec_as_function.h"
 #include "swfdec_as_number.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_movie.h"
 
diff-tree fe60ff709e503e0efd1e5d025f8fdb1c91052331 (from a2b711fdfdbe4fedd7f9b8bfe45e5c3b32c99cc2)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:56:01 2007 +0100

    actually install the headers, not the source files (oops)

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 0296531..e91b587 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_context.c \
 	swfdec_as_frame.c \
 	swfdec_as_function.c \
 	swfdec_as_interpret.c \
@@ -34,6 +35,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_as_string.c \
 	swfdec_as_strings.c \
 	swfdec_as_super.c \
+	swfdec_as_types.c \
 	swfdec_as_with.c \
 	swfdec_amf.c \
 	swfdec_audio.c \
@@ -117,8 +119,8 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_LDFLAGS
 
 public_headers = \
 	swfdec.h \
-	swfdec_as_context.c \
-	swfdec_as_types.c \
+	swfdec_as_context.h \
+	swfdec_as_types.h \
 	swfdec_audio.h \
 	swfdec_buffer.h \
 	swfdec_loader.h \
@@ -130,7 +132,6 @@ libswfdec_ at SWFDEC_MAJORMINOR@include_HEA
 
 noinst_HEADERS = \
 	swfdec_as_array.h \
-	swfdec_as_context.h \
 	swfdec_as_frame.h \
 	swfdec_as_function.h \
 	swfdec_as_interpret.h \
@@ -144,7 +145,6 @@ noinst_HEADERS = \
 	swfdec_as_string.h \
 	swfdec_as_strings.h \
 	swfdec_as_super.h \
-	swfdec_as_types.h \
 	swfdec_as_with.h \
 	swfdec_amf.h \
 	swfdec_audio_internal.h \
diff-tree a2b711fdfdbe4fedd7f9b8bfe45e5c3b32c99cc2 (from 7b13df81056de92872df2572d08c2dffe5fed171)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:54:37 2007 +0100

    make GC flags local

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 03b0c5e..a79fc66 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -40,6 +40,9 @@
 
 /*** GARBAGE COLLECTION DOCS ***/
 
+#define SWFDEC_AS_GC_MARK (1 << 0)		/* only valid during GC */
+#define SWFDEC_AS_GC_ROOT (1 << 1)		/* for objects: rooted, for strings: static */
+
 /**
  * SECTION:Internals
  * @title: Internals and garbage collection
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index c93d16f..a416b0e 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -32,9 +32,6 @@ typedef enum {
   SWFDEC_AS_CONTEXT_ABORTED
 } SwfdecAsContextState;
 
-#define SWFDEC_AS_GC_MARK (1 << 0)		/* only valid during GC */
-#define SWFDEC_AS_GC_ROOT (1 << 1)		/* for objects: rooted, for strings: static */
-
 typedef struct _SwfdecAsContextClass SwfdecAsContextClass;
 
 #define SWFDEC_TYPE_AS_CONTEXT                    (swfdec_as_context_get_type())
diff-tree 7b13df81056de92872df2572d08c2dffe5fed171 (from 4d16d4a8f6deaa31ef06bece61b4bf7adba53d18)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:53:19 2007 +0100

    don't include swfdec_as_strings.h in swfdec_as_types.h

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index 620bc8b..1ec58c2 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -29,6 +29,7 @@
 #include "swfdec_as_frame.h"
 #include "swfdec_as_function.h"
 #include "swfdec_as_native_function.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 
 G_DEFINE_TYPE (SwfdecAsArray, swfdec_as_array, SWFDEC_TYPE_AS_OBJECT)
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index d05ba82..a5718bd 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -25,6 +25,7 @@
 #include "swfdec_as_array.h"
 #include "swfdec_as_context.h"
 #include "swfdec_as_stack.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_as_super.h"
 #include "swfdec_debug.h"
 
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index c74302e..9465ebc 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -25,6 +25,7 @@
 #include "swfdec_as_context.h"
 #include "swfdec_as_frame.h"
 #include "swfdec_as_stack.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 
 G_DEFINE_ABSTRACT_TYPE (SwfdecAsFunction, swfdec_as_function, SWFDEC_TYPE_AS_OBJECT)
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 3b7f5e9..3195a8c 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -27,6 +27,7 @@
 #include "swfdec_as_function.h"
 #include "swfdec_as_script_function.h"
 #include "swfdec_as_stack.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_as_with.h"
 #include "swfdec_debug.h"
 
diff --git a/libswfdec/swfdec_as_math.c b/libswfdec/swfdec_as_math.c
index cfc5fc1..ddd6987 100644
--- a/libswfdec/swfdec_as_math.c
+++ b/libswfdec/swfdec_as_math.c
@@ -26,6 +26,7 @@
 #include "swfdec_as_math.h"
 #include "swfdec_as_object.h"
 #include "swfdec_as_context.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 
 /*** AS CODE ***/
diff --git a/libswfdec/swfdec_as_number.c b/libswfdec/swfdec_as_number.c
index dec4599..5127102 100644
--- a/libswfdec/swfdec_as_number.c
+++ b/libswfdec/swfdec_as_number.c
@@ -27,6 +27,7 @@
 #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 (SwfdecAsNumber, swfdec_as_number, SWFDEC_TYPE_AS_OBJECT)
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 721d74b..34b1ee5 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -27,6 +27,7 @@
 #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"
 
 
diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index 922b02c..78bf52d 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -25,6 +25,7 @@
 #include "swfdec_as_context.h"
 #include "swfdec_as_frame.h"
 #include "swfdec_as_stack.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 
 G_DEFINE_TYPE (SwfdecAsScriptFunction, swfdec_as_script_function, SWFDEC_TYPE_AS_FUNCTION)
diff --git a/libswfdec/swfdec_as_string.c b/libswfdec/swfdec_as_string.c
index 8515c7c..c7babe3 100644
--- a/libswfdec/swfdec_as_string.c
+++ b/libswfdec/swfdec_as_string.c
@@ -29,6 +29,7 @@
 #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 (SwfdecAsString, swfdec_as_string, SWFDEC_TYPE_AS_OBJECT)
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index 730748c..bb5b231 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -27,6 +27,7 @@
 #include "swfdec_as_context.h"
 #include "swfdec_as_frame.h"
 #include "swfdec_as_function.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 
 G_DEFINE_TYPE (SwfdecAsSuper, swfdec_as_super, SWFDEC_TYPE_AS_FUNCTION)
diff --git a/libswfdec/swfdec_as_types.h b/libswfdec/swfdec_as_types.h
index 2a8cb79..a44d041 100644
--- a/libswfdec/swfdec_as_types.h
+++ b/libswfdec/swfdec_as_types.h
@@ -22,8 +22,6 @@
 
 #include <glib.h>
 
-#include "swfdec_as_strings.h"
-
 G_BEGIN_DECLS
 
 /* fundamental types */
diff --git a/libswfdec/swfdec_button_movie.c b/libswfdec/swfdec_button_movie.c
index efa23b6..0d9a57c 100644
--- a/libswfdec/swfdec_button_movie.c
+++ b/libswfdec/swfdec_button_movie.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "swfdec_button_movie.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_audio_event.h"
 #include "swfdec_debug.h"
 #include "swfdec_event.h"
diff --git a/libswfdec/swfdec_color_as.c b/libswfdec/swfdec_color_as.c
index 8ebefe5..60a95d3 100644
--- a/libswfdec/swfdec_color_as.c
+++ b/libswfdec/swfdec_color_as.c
@@ -24,6 +24,7 @@
 #include "swfdec_color_as.h"
 #include "swfdec_as_context.h"
 #include "swfdec_as_native_function.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_movie.h"
 
diff --git a/libswfdec/swfdec_edittext_movie.c b/libswfdec/swfdec_edittext_movie.c
index 1243da8..0613025 100644
--- a/libswfdec/swfdec_edittext_movie.c
+++ b/libswfdec/swfdec_edittext_movie.c
@@ -23,6 +23,7 @@
 
 #include "swfdec_edittext_movie.h"
 #include "swfdec_as_context.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
 
diff --git a/libswfdec/swfdec_event.c b/libswfdec/swfdec_event.c
index 227c569..6452829 100644
--- a/libswfdec/swfdec_event.c
+++ b/libswfdec/swfdec_event.c
@@ -22,6 +22,7 @@
 #endif
 #include "swfdec_event.h"
 #include "swfdec_as_object.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
 #include "swfdec_script.h"
diff --git a/libswfdec/swfdec_mouse_as.c b/libswfdec/swfdec_mouse_as.c
index 3a39619..c5d6f49 100644
--- a/libswfdec/swfdec_mouse_as.c
+++ b/libswfdec/swfdec_mouse_as.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "swfdec_as_object.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_listener.h"
 #include "swfdec_player_internal.h"
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index d428eb3..463b5ba 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -29,6 +29,7 @@
 
 #include "swfdec_movie.h"
 #include "swfdec_as_context.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_button_movie.h"
 #include "swfdec_debug.h"
 #include "swfdec_debugger.h"
diff --git a/libswfdec/swfdec_movie_asprops.c b/libswfdec/swfdec_movie_asprops.c
index cf9102e..8a1518f 100644
--- a/libswfdec/swfdec_movie_asprops.c
+++ b/libswfdec/swfdec_movie_asprops.c
@@ -26,6 +26,7 @@
 #include <math.h>
 
 #include "swfdec_movie.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_bits.h"
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
diff --git a/libswfdec/swfdec_net_connection.c b/libswfdec/swfdec_net_connection.c
index d6df7d1..6ba01bf 100644
--- a/libswfdec/swfdec_net_connection.c
+++ b/libswfdec/swfdec_net_connection.c
@@ -24,8 +24,9 @@
 #include <string.h>
 #include "swfdec_net_connection.h"
 #include "swfdec_as_context.h"
-#include "swfdec_as_object.h"
 #include "swfdec_as_native_function.h"
+#include "swfdec_as_object.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 
 /*** SwfdecNetConnection ***/
diff --git a/libswfdec/swfdec_net_stream.c b/libswfdec/swfdec_net_stream.c
index 0635921..7cdd203 100644
--- a/libswfdec/swfdec_net_stream.c
+++ b/libswfdec/swfdec_net_stream.c
@@ -24,6 +24,7 @@
 #include <math.h>
 #include "swfdec_net_stream.h"
 #include "swfdec_amf.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_audio_flv.h"
 #include "swfdec_debug.h"
 #include "swfdec_loader_internal.h"
diff --git a/libswfdec/swfdec_net_stream_as.c b/libswfdec/swfdec_net_stream_as.c
index 69dd38c..8ce397e 100644
--- a/libswfdec/swfdec_net_stream_as.c
+++ b/libswfdec/swfdec_net_stream_as.c
@@ -25,6 +25,7 @@
 #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"
 #include "swfdec_player_internal.h"
 
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 554d22b..60a1847 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -27,6 +27,7 @@
 #include <liboil/liboil.h>
 
 #include "swfdec_player_internal.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_audio_internal.h"
 #include "swfdec_button_movie.h" /* for mouse cursor */
 #include "swfdec_cache.h"
diff --git a/libswfdec/swfdec_player_as.c b/libswfdec/swfdec_player_as.c
index e983c6f..bb42da1 100644
--- a/libswfdec/swfdec_player_as.c
+++ b/libswfdec/swfdec_player_as.c
@@ -24,6 +24,7 @@
 #include "swfdec_player_internal.h"
 #include "swfdec_as_function.h"
 #include "swfdec_as_object.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_interval.h"
 
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 1712104..14ce0ff 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -25,6 +25,7 @@
 
 #include "swfdec_sprite_movie.h"
 #include "swfdec_as_object.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_audio_event.h"
 #include "swfdec_audio_stream.h"
 #include "swfdec_debug.h"
diff --git a/libswfdec/swfdec_sprite_movie_as.c b/libswfdec/swfdec_sprite_movie_as.c
index fd3a601..35e069e 100644
--- a/libswfdec/swfdec_sprite_movie_as.c
+++ b/libswfdec/swfdec_sprite_movie_as.c
@@ -24,6 +24,7 @@
 #endif
 
 #include "swfdec_movie.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_bits.h"
 #include "swfdec_debug.h"
 #include "swfdec_decoder.h"
diff --git a/libswfdec/swfdec_video_movie_as.c b/libswfdec/swfdec_video_movie_as.c
index ad45317..e0fe763 100644
--- a/libswfdec/swfdec_video_movie_as.c
+++ b/libswfdec/swfdec_video_movie_as.c
@@ -22,6 +22,7 @@
 #endif
 
 #include "swfdec_video.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_net_stream.h"
 #include "swfdec_player_internal.h"
diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c
index fd9d96a..404ec38 100644
--- a/libswfdec/swfdec_xml.c
+++ b/libswfdec/swfdec_xml.c
@@ -23,6 +23,7 @@
 
 #include <string.h>
 #include "swfdec_xml.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_loader_internal.h"
 #include "swfdec_loadertarget.h"
diff --git a/libswfdec/swfdec_xml_as.c b/libswfdec/swfdec_xml_as.c
index 8be7ae3..69b7932 100644
--- a/libswfdec/swfdec_xml_as.c
+++ b/libswfdec/swfdec_xml_as.c
@@ -24,6 +24,7 @@
 #include "swfdec_xml.h"
 #include "swfdec_as_native_function.h"
 #include "swfdec_as_object.h"
+#include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_player_internal.h"
 
diff-tree 4d16d4a8f6deaa31ef06bece61b4bf7adba53d18 (from c8cb8271105594fbbaa40ae71c855756f952aef5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:47:51 2007 +0100

    make swfdec_as_types.h and swfdec_as_context.h public headers

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 62363b3..0296531 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -21,7 +21,6 @@ lib_LTLIBRARIES = libswfdec- at SWFDEC_MAJO
 
 libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES = \
 	swfdec_as_array.c \
-	swfdec_as_context.c \
 	swfdec_as_frame.c \
 	swfdec_as_function.c \
 	swfdec_as_interpret.c \
@@ -35,7 +34,6 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_as_string.c \
 	swfdec_as_strings.c \
 	swfdec_as_super.c \
-	swfdec_as_types.c \
 	swfdec_as_with.c \
 	swfdec_amf.c \
 	swfdec_audio.c \
@@ -119,6 +117,8 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_LDFLAGS
 
 public_headers = \
 	swfdec.h \
+	swfdec_as_context.c \
+	swfdec_as_types.c \
 	swfdec_audio.h \
 	swfdec_buffer.h \
 	swfdec_loader.h \
diff --git a/libswfdec/swfdec.h b/libswfdec/swfdec.h
index 4c66a69..c527798 100644
--- a/libswfdec/swfdec.h
+++ b/libswfdec/swfdec.h
@@ -28,4 +28,7 @@
 #include <libswfdec/swfdec_loader.h>
 #include <libswfdec/swfdec_player.h>
 
+#include <libswfdec/swfdec_as_context.h>
+#include <libswfdec/swfdec_as_types.h>
+
 #endif
diff-tree c8cb8271105594fbbaa40ae71c855756f952aef5 (from 2a76c374147a5170e52ede7a70d0b6610085167b)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:44:24 2007 +0100

    add test that makes sure aborted script engines stay aborted

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 9b9592c..e303d77 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -14,6 +14,13 @@ trace_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_L
 
 EXTRA_DIST = \
 	README \
+	abort-really-aborts.as \
+	abort-really-aborts-5.swf \
+	abort-really-aborts-5.swf.trace \
+	abort-really-aborts-6.swf \
+	abort-really-aborts-6.swf.trace \
+	abort-really-aborts-7.swf \
+	abort-really-aborts-7.swf.trace \
 	add2.as \
 	add2-5.swf \
 	add2-5.swf.trace \
diff --git a/test/trace/abort-really-aborts-5.swf b/test/trace/abort-really-aborts-5.swf
new file mode 100644
index 0000000..26eee79
Binary files /dev/null and b/test/trace/abort-really-aborts-5.swf differ
diff --git a/test/trace/abort-really-aborts-5.swf.trace b/test/trace/abort-really-aborts-5.swf.trace
new file mode 100644
index 0000000..7bf0d18
--- /dev/null
+++ b/test/trace/abort-really-aborts-5.swf.trace
@@ -0,0 +1 @@
+Check that abort really aborts script execution forever
diff --git a/test/trace/abort-really-aborts-6.swf b/test/trace/abort-really-aborts-6.swf
new file mode 100644
index 0000000..43a78f6
Binary files /dev/null and b/test/trace/abort-really-aborts-6.swf differ
diff --git a/test/trace/abort-really-aborts-6.swf.trace b/test/trace/abort-really-aborts-6.swf.trace
new file mode 100644
index 0000000..7bf0d18
--- /dev/null
+++ b/test/trace/abort-really-aborts-6.swf.trace
@@ -0,0 +1 @@
+Check that abort really aborts script execution forever
diff --git a/test/trace/abort-really-aborts-7.swf b/test/trace/abort-really-aborts-7.swf
new file mode 100644
index 0000000..3f5aaaf
Binary files /dev/null and b/test/trace/abort-really-aborts-7.swf differ
diff --git a/test/trace/abort-really-aborts-7.swf.trace b/test/trace/abort-really-aborts-7.swf.trace
new file mode 100644
index 0000000..7bf0d18
--- /dev/null
+++ b/test/trace/abort-really-aborts-7.swf.trace
@@ -0,0 +1 @@
+Check that abort really aborts script execution forever
diff --git a/test/trace/abort-really-aborts.as b/test/trace/abort-really-aborts.as
new file mode 100644
index 0000000..e9e19f1
--- /dev/null
+++ b/test/trace/abort-really-aborts.as
@@ -0,0 +1,13 @@
+// makeswf -v 7 -s 200x150 -r 1 -o abort-really-aborts.swf abort-really-aborts.as
+
+trace ("Check that abort really aborts script execution forever");
+
+createEmptyMovieClip ("movie", 0);
+movie.onEnterFrame = function () {
+  trace ("hi");
+};
+
+function foo () {
+  foo ();
+};
+foo ();
diff-tree 2a76c374147a5170e52ede7a70d0b6610085167b (from f5db560ccd64e25f6020dac7b4535aba8e9a8ad1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:43:10 2007 +0100

    check the the stack overflows correctly

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 930a5d8..9b9592c 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -643,6 +643,13 @@ EXTRA_DIST = \
 	shift-6.swf.trace \
 	shift-7.swf \
 	shift-7.swf.trace \
+	stack-overflow.as \
+	stack-overflow-5.swf \
+	stack-overflow-5.swf.trace \
+	stack-overflow-6.swf \
+	stack-overflow-6.swf.trace \
+	stack-overflow-7.swf \
+	stack-overflow-7.swf.trace \
 	string-construct.as \
 	string-construct-5.swf \
 	string-construct-5.swf.trace \
diff --git a/test/trace/stack-overflow-5.swf b/test/trace/stack-overflow-5.swf
new file mode 100644
index 0000000..3a8b8c8
Binary files /dev/null and b/test/trace/stack-overflow-5.swf differ
diff --git a/test/trace/stack-overflow-5.swf.trace b/test/trace/stack-overflow-5.swf.trace
new file mode 100644
index 0000000..bd1bd80
--- /dev/null
+++ b/test/trace/stack-overflow-5.swf.trace
@@ -0,0 +1,256 @@
+Check the stack overflows correctly
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
diff --git a/test/trace/stack-overflow-6.swf b/test/trace/stack-overflow-6.swf
new file mode 100644
index 0000000..eb1df84
Binary files /dev/null and b/test/trace/stack-overflow-6.swf differ
diff --git a/test/trace/stack-overflow-6.swf.trace b/test/trace/stack-overflow-6.swf.trace
new file mode 100644
index 0000000..bd1bd80
--- /dev/null
+++ b/test/trace/stack-overflow-6.swf.trace
@@ -0,0 +1,256 @@
+Check the stack overflows correctly
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
diff --git a/test/trace/stack-overflow-7.swf b/test/trace/stack-overflow-7.swf
new file mode 100644
index 0000000..2a07034
Binary files /dev/null and b/test/trace/stack-overflow-7.swf differ
diff --git a/test/trace/stack-overflow-7.swf.trace b/test/trace/stack-overflow-7.swf.trace
new file mode 100644
index 0000000..bd1bd80
--- /dev/null
+++ b/test/trace/stack-overflow-7.swf.trace
@@ -0,0 +1,256 @@
+Check the stack overflows correctly
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
diff --git a/test/trace/stack-overflow.as b/test/trace/stack-overflow.as
new file mode 100644
index 0000000..70b7d19
--- /dev/null
+++ b/test/trace/stack-overflow.as
@@ -0,0 +1,13 @@
+// makeswf -v 7 -s 200x150 -r 1 -o stack-overflow.swf stack-overflow.as
+
+trace ("Check the stack overflows correctly");
+i = 1;
+function foo () {
+  trace (i);
+  i++;
+  foo ();
+};
+foo ();
+trace ("done @ " + i);
+
+loadMovie ("FSCommand:quit", "");
diff-tree f5db560ccd64e25f6020dac7b4535aba8e9a8ad1 (from 1cf578b236785ab47c3735c5c32e2eaefc077ae5)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:34:34 2007 +0100

    new frames can be NULL

diff --git a/libswfdec/swfdec_as_native_function.c b/libswfdec/swfdec_as_native_function.c
index 0905178..87f937d 100644
--- a/libswfdec/swfdec_as_native_function.c
+++ b/libswfdec/swfdec_as_native_function.c
@@ -51,6 +51,8 @@ swfdec_as_native_function_call (SwfdecAs
   SwfdecAsFrame *frame;
 
   frame = swfdec_as_frame_new_native (SWFDEC_AS_OBJECT (function)->context);
+  if (frame == NULL)
+    return NULL;
   g_assert (native->name);
   frame->function_name = native->name;
   frame->function = function;
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index 72dc8d2..730748c 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -53,6 +53,8 @@ swfdec_as_super_call (SwfdecAsFunction *
 
   klass = SWFDEC_AS_FUNCTION_GET_CLASS (fun);
   frame = klass->call (fun);
+  if (frame == NULL)
+    return NULL;
   /* We set the real function here. 1) swfdec_as_context_run() requires it. 
    * And b) it makes more sense reading the constructor's name than reading "super" 
    * in a debugger
diff-tree 1cf578b236785ab47c3735c5c32e2eaefc077ae5 (from ac1343606dba8169ab163a97a564cde0bbe22a7a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:34:26 2007 +0100

    really abort when we abort

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 5b8079b..03b0c5e 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -586,7 +586,7 @@ swfdec_as_context_run (SwfdecAsContext *
   gboolean check_scope; /* some opcodes avoid a scope check */
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
-  if (context->frame == NULL)
+  if (context->frame == NULL || context->state == SWFDEC_AS_CONTEXT_ABORTED)
     return;
 
   klass = SWFDEC_AS_CONTEXT_GET_CLASS (context);
@@ -627,7 +627,7 @@ start:
   pc = frame->pc;
   check_scope = TRUE;
 
-  while (TRUE) {
+  while (context->state < SWFDEC_AS_CONTEXT_ABORTED) {
     if (pc == endpc) {
       swfdec_as_frame_return (frame);
       goto start;
diff-tree ac1343606dba8169ab163a97a564cde0bbe22a7a (from 2e1af44affe8e070f1f649c5f36fb922015a003f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:31:34 2007 +0100

    the frame can be NULL, too

diff --git a/libswfdec/swfdec_as_script_function.c b/libswfdec/swfdec_as_script_function.c
index 3140143..922b02c 100644
--- a/libswfdec/swfdec_as_script_function.c
+++ b/libswfdec/swfdec_as_script_function.c
@@ -36,6 +36,8 @@ swfdec_as_script_function_call (SwfdecAs
   SwfdecAsFrame *frame;
 
   frame = swfdec_as_frame_new (SWFDEC_AS_OBJECT (function)->context, script->script);
+  if (frame == NULL)
+    return NULL;
   SWFDEC_AS_SCOPE (frame)->next = script->scope;
   frame->function = function;
   frame->target = script->target;
diff-tree 2e1af44affe8e070f1f649c5f36fb922015a003f (from 83a8cc868639af2df66fc30cf0b31dcba6858849)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:26:56 2007 +0100

    allow aborting twice

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 6f8a6f8..5b8079b 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -152,7 +152,6 @@ void
 swfdec_as_context_abort (SwfdecAsContext *context, const char *reason)
 {
   g_return_if_fail (context);
-  g_return_if_fail (context->state != SWFDEC_AS_CONTEXT_ABORTED);
 
   SWFDEC_ERROR (reason);
   context->state = SWFDEC_AS_CONTEXT_ABORTED;
diff-tree 83a8cc868639af2df66fc30cf0b31dcba6858849 (from 053ab136afc68c43aef3b500f56bf5acead107e6)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:26:28 2007 +0100

    remove swfdec_as_context_trace and call it directly from the trace action
    
    Don't call it on abort anymore.

diff --git a/doc/swfdec-sections.txt b/doc/swfdec-sections.txt
index d147bdd..70e8128 100644
--- a/doc/swfdec-sections.txt
+++ b/doc/swfdec-sections.txt
@@ -237,7 +237,6 @@ swfdec_as_context_new
 swfdec_as_context_return
 swfdec_as_context_run
 swfdec_as_context_startup
-swfdec_as_context_trace
 swfdec_as_context_unuse_mem
 swfdec_as_context_use_mem
 <SUBSECTION Standard>
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index f8bcc4c..6f8a6f8 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -156,7 +156,6 @@ swfdec_as_context_abort (SwfdecAsContext
 
   SWFDEC_ERROR (reason);
   context->state = SWFDEC_AS_CONTEXT_ABORTED;
-  swfdec_as_context_trace (context, reason);
 }
 
 /*** MEMORY MANAGEMENT ***/
@@ -727,22 +726,6 @@ out:
   return;
 }
 
-/**
- * swfdec_as_context_trace:
- * @context: a #SwfdecAsContext
- * @string: a string to output
- *
- * Causes the emission of the trace signal with the provided @string.
- **/
-void
-swfdec_as_context_trace (SwfdecAsContext *context, const char *string)
-{
-  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
-  g_return_if_fail (string != NULL);
-
-  g_signal_emit (context, signals[TRACE], 0, string);
-}
-
 /*** EVAL ***/
 
 char *
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 57eda85..c93d16f 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -114,8 +114,6 @@ void		swfdec_as_context_gc		(SwfdecAsCon
 void		swfdec_as_context_maybe_gc	(SwfdecAsContext *	context);
 
 void		swfdec_as_context_run		(SwfdecAsContext *	context);
-void		swfdec_as_context_trace		(SwfdecAsContext *	context,
-						 const char *		string);
 
 void		swfdec_as_context_eval		(SwfdecAsContext *	context,
 						 SwfdecAsObject *	obj,
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 396fa7b..3b7f5e9 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -552,7 +552,7 @@ swfdec_action_trace (SwfdecAsContext *cx
     s = SWFDEC_AS_STR_undefined;
   else
     s = swfdec_as_value_to_string (cx, val);
-  swfdec_as_context_trace (cx, s);
+  g_signal_emit_by_name (cx, "trace", s);
 }
 
 /* stack looks like this: [ function, this, arg1, arg2, ... ] */
diff-tree 053ab136afc68c43aef3b500f56bf5acead107e6 (from 41035d740f3910c483715f157f20845c14074794)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:23:50 2007 +0100

    Abort on stack overflow
    
    And don't do stupid things if we actually have aborted

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index b869b12..f8bcc4c 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -66,7 +66,7 @@
  * swfdec_as_context_startup (). At that point, the basic objects are created.
  * After this function has been called, you can start executing code. All code
  * execution happens by creating a new #SwfdecAsFrame and then calling 
- * swfdec_as_context_run () to execute it. This function is the single entry 
+ * swfdec_as_context_run() to execute it. This function is the single entry 
  * point for code execution. Convenience functions exist that make executing 
  * code easy, most notably swfdec_as_object_run() and 
  * swfdec_as_object_call().
@@ -179,6 +179,9 @@ swfdec_as_context_use_mem (SwfdecAsConte
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), FALSE);
   g_return_val_if_fail (bytes > 0, FALSE);
 
+  if (context->state == SWFDEC_AS_CONTEXT_ABORTED)
+    return FALSE;
+  
   context->memory += bytes;
   context->memory_since_gc += bytes;
   /* FIXME: Don't foget to abort on OOM */
@@ -356,6 +359,8 @@ swfdec_as_context_gc (SwfdecAsContext *c
   g_return_if_fail (context->frame == NULL);
   g_return_if_fail (context->state != SWFDEC_AS_CONTEXT_NEW);
 
+  if (context->state == SWFDEC_AS_CONTEXT_ABORTED)
+    return;
   SWFDEC_INFO ("invoking the garbage collector");
   klass = SWFDEC_AS_CONTEXT_GET_CLASS (context);
   g_assert (klass->mark);
@@ -383,6 +388,8 @@ void
 swfdec_as_context_maybe_gc (SwfdecAsContext *context)
 {
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
+  if (context->state == SWFDEC_AS_CONTEXT_ABORTED)
+    return;
   g_return_if_fail (context->frame == NULL);
 
   if (swfdec_as_context_needs_gc (context))
@@ -594,6 +601,11 @@ start:
   frame = context->frame;
   if (frame == context->last_frame)
     goto out;
+  if (context->call_depth > 256) {
+    /* we've exceeded our maximum call depth, throw an error and abort */
+    swfdec_as_context_abort (context, "Stack overflow");
+    return;
+  }
   if (SWFDEC_IS_AS_NATIVE_FUNCTION (frame->function)) {
     SwfdecAsNativeFunction *native = SWFDEC_AS_NATIVE_FUNCTION (frame->function);
     if (frame->argc >= native->min_args && 
diff-tree 41035d740f3910c483715f157f20845c14074794 (from f24ac118ee47065dac5b9f9c5fea1d98072485dc)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Jul 1 00:20:06 2007 +0100

    Array creation does not call the array constructor.
    
    FIXME: Should it? Or maybe only sometimes?

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index dc2fc56..620bc8b 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -118,8 +118,7 @@ swfdec_as_array_init (SwfdecAsArray *arr
  * swfdec_as_array_new:
  * @context: a #SwfdecAsContext
  *
- * Creates a new #SwfdecAsArray. This is the same as executing the Actionscript
- * code "new Array ()"
+ * Creates a new #SwfdecAsArray. 
  *
  * Returns: the new array or %NULL on OOM.
  **/
@@ -131,8 +130,11 @@ swfdec_as_array_new (SwfdecAsContext *co
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
   g_return_val_if_fail (context->Array != NULL, NULL);
   
-  ret = swfdec_as_object_create (SWFDEC_AS_FUNCTION (context->Array), 0, NULL, FALSE);
-  swfdec_as_context_run (context);
+  if (!swfdec_as_context_use_mem (context, sizeof (SwfdecAsArray)))
+    return FALSE;
+  ret = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL);
+  swfdec_as_object_add (ret, context, sizeof (SwfdecAsArray));
+  swfdec_as_object_set_constructor (ret, context->Array, FALSE);
   return ret;
 }
 
diff-tree f24ac118ee47065dac5b9f9c5fea1d98072485dc (from e9684a012bd9666299ff7b6c03e55ac0d48f479a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat Jun 30 19:42:45 2007 +0100

    make the context keep track of the call stack depth

diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index e051d2c..57eda85 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -63,6 +63,7 @@ struct _SwfdecAsContext {
 
   /* execution state */
   unsigned int	      	version;	/* currently active version */
+  unsigned int		call_depth;   	/* current depth of call stack (equals length of frame list) */
   SwfdecAsFrame *	frame;		/* topmost stack frame */
   SwfdecAsFrame *	last_frame;   	/* last frame before calling context_run */
 
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 5f33620..d05ba82 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -97,6 +97,16 @@ swfdec_as_frame_init (SwfdecAsFrame *fra
   frame->function_name = "unnamed";
 }
 
+static void
+swfdec_as_frame_load (SwfdecAsFrame *frame)
+{
+  SwfdecAsContext *context = SWFDEC_AS_OBJECT (frame)->context;
+
+  frame->next = context->frame;
+  context->frame = frame;
+  context->call_depth++;
+}
+
 SwfdecAsFrame *
 swfdec_as_frame_new (SwfdecAsContext *context, SwfdecScript *script)
 {
@@ -133,8 +143,7 @@ swfdec_as_frame_new (SwfdecAsContext *co
       SWFDEC_ERROR ("couldn't create constant pool");
     }
   }
-  frame->next = context->frame;
-  context->frame = frame;
+  swfdec_as_frame_load (frame);
   return frame;
 }
 
@@ -152,8 +161,7 @@ swfdec_as_frame_new_native (SwfdecAsCont
   frame = g_object_new (SWFDEC_TYPE_AS_FRAME, NULL);
   SWFDEC_DEBUG ("new native frame");
   swfdec_as_object_add (SWFDEC_AS_OBJECT (frame), context, size);
-  frame->next = context->frame;
-  context->frame = frame;
+  swfdec_as_frame_load (frame);
   return frame;
 }
 
@@ -174,6 +182,8 @@ swfdec_as_frame_return (SwfdecAsFrame *f
   g_return_if_fail (frame == context->frame);
 
   context->frame = frame->next;
+  g_assert (context->call_depth > 0);
+  context->call_depth--;
 }
 
 /**
diff-tree e9684a012bd9666299ff7b6c03e55ac0d48f479a (from 81107e1714a4e0d3ed8161587d153697f4a27398)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat Jun 30 19:38:12 2007 +0100

    Set a frame as the context's current frame on frame creation

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index f60876c..5f33620 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -133,6 +133,8 @@ swfdec_as_frame_new (SwfdecAsContext *co
       SWFDEC_ERROR ("couldn't create constant pool");
     }
   }
+  frame->next = context->frame;
+  context->frame = frame;
   return frame;
 }
 
@@ -150,6 +152,8 @@ swfdec_as_frame_new_native (SwfdecAsCont
   frame = g_object_new (SWFDEC_TYPE_AS_FRAME, NULL);
   SWFDEC_DEBUG ("new native frame");
   swfdec_as_object_add (SWFDEC_AS_OBJECT (frame), context, size);
+  frame->next = context->frame;
+  context->frame = frame;
   return frame;
 }
 
diff --git a/libswfdec/swfdec_as_function.c b/libswfdec/swfdec_as_function.c
index aee6b90..c74302e 100644
--- a/libswfdec/swfdec_as_function.c
+++ b/libswfdec/swfdec_as_function.c
@@ -94,9 +94,6 @@ swfdec_as_function_call (SwfdecAsFunctio
   frame->argv = args;
   frame->return_value = return_value;
   swfdec_as_frame_preload (frame);
-  /* FIXME: make this a seperate function? */
-  frame->next = context->frame;
-  context->frame = frame;
 }
 
 /*** AS CODE ***/
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 339bf23..721d74b 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -470,8 +470,6 @@ swfdec_as_object_run (SwfdecAsObject *ob
   frame = swfdec_as_frame_new (object->context, script);
   if (frame == NULL)
     return;
-  frame->next = object->context->frame;
-  object->context->frame = frame;
   swfdec_as_frame_set_this (frame, object);
   swfdec_as_frame_preload (frame);
   swfdec_as_context_run (object->context);
diff-tree 81107e1714a4e0d3ed8161587d153697f4a27398 (from d8fb7ee0521b6fa84a3a9facb960e501b69212f2)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat Jun 30 19:26:52 2007 +0100

    remove swfdec_as_object_(un)root()
    
    rooting isn't needed anymore, since the GC isn't run automatically anymore.

diff --git a/libswfdec/swfdec_amf.c b/libswfdec/swfdec_amf.c
index 88f87ad..341976e 100644
--- a/libswfdec/swfdec_amf.c
+++ b/libswfdec/swfdec_amf.c
@@ -61,8 +61,6 @@ swfdec_amf_parse_properties (SwfdecAsCon
   guint type;
   SwfdecAmfParseFunc func;
 
-  /* need to root here due to GC */
-  swfdec_as_object_root (object);
   while (swfdec_bits_left (bits)) {
     SwfdecAsValue val;
     const char *name;
@@ -85,11 +83,9 @@ swfdec_amf_parse_properties (SwfdecAsCon
     swfdec_as_object_set_variable (object, name, &val);
   }
   /* no more bytes seems to end automatically */
-  swfdec_as_object_unroot (object);
   return TRUE;
 
 error:
-  swfdec_as_object_unroot (object);
   return FALSE;
 }
 
@@ -135,7 +131,6 @@ swfdec_amf_parse_array (SwfdecAsContext 
   array = swfdec_as_array_new (context);
   if (array == NULL)
     return FALSE;
-  swfdec_as_object_root (array);
   for (i = 0; i < len; i++) {
     type = swfdec_bits_get_u8 (bits);
     SwfdecAsValue val;
@@ -149,12 +144,10 @@ swfdec_amf_parse_array (SwfdecAsContext 
     swfdec_as_array_push (SWFDEC_AS_ARRAY (array), &val);
   }
 
-  swfdec_as_object_unroot (array);
   SWFDEC_AS_VALUE_SET_OBJECT (val, array);
   return TRUE;
 
 fail:
-  swfdec_as_object_unroot (array);
   return FALSE;
 }
 
@@ -207,7 +200,6 @@ swfdec_amf_parse_one (SwfdecAsContext *c
   return func (context, bits, rval);
 }
 
-/* FIXME: parsed values aren't gc rooted... */
 guint
 swfdec_amf_parse (SwfdecAsContext *context, SwfdecBits *bits, guint n_items, ...)
 {
diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index 7415667..dc2fc56 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -132,9 +132,7 @@ swfdec_as_array_new (SwfdecAsContext *co
   g_return_val_if_fail (context->Array != NULL, NULL);
   
   ret = swfdec_as_object_create (SWFDEC_AS_FUNCTION (context->Array), 0, NULL, FALSE);
-  swfdec_as_object_root (ret);
   swfdec_as_context_run (context);
-  swfdec_as_object_unroot (ret);
   return ret;
 }
 
@@ -246,10 +244,8 @@ swfdec_as_array_init_context (SwfdecAsCo
   proto = g_object_new (SWFDEC_TYPE_AS_ARRAY, NULL);
   swfdec_as_object_add (proto, context, sizeof (SwfdecAsArray));
   /* set the right properties on the Array object */
-  swfdec_as_object_root (proto);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
   swfdec_as_object_set_variable (array, SWFDEC_AS_STR_prototype, &val);
-  swfdec_as_object_unroot (proto);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, context->Function);
   swfdec_as_object_set_variable (array, SWFDEC_AS_STR_constructor, &val);
   SWFDEC_AS_VALUE_SET_NUMBER (&val, 1);
diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 49b4d38..b869b12 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -603,7 +603,7 @@ start:
       native->native (context, frame->thisp, frame->argc, 
 	  (SwfdecAsValue *) frame->argv, frame->return_value);
     }
-    swfdec_as_context_return (context);
+    swfdec_as_frame_return (frame);
     goto start;
   }
   g_assert (frame->script);
@@ -619,7 +619,7 @@ start:
 
   while (TRUE) {
     if (pc == endpc) {
-      swfdec_as_context_return (context);
+      swfdec_as_frame_return (frame);
       goto start;
     }
     if (pc < startpc || pc >= endpc) {
@@ -632,7 +632,7 @@ start:
     /* decode next action */
     action = *pc;
     if (action == 0) {
-      swfdec_as_context_return (context);
+      swfdec_as_frame_return (frame);
       goto start;
     }
     /* invoke debugger if there is one */
@@ -715,15 +715,6 @@ out:
   return;
 }
 
-void
-swfdec_as_context_return (SwfdecAsContext *context)
-{
-  g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
-  g_return_if_fail (context->frame != NULL);
-
-  context->frame = context->frame->next;
-}
-
 /**
  * swfdec_as_context_trace:
  * @context: a #SwfdecAsContext
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index 37c5251..e051d2c 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -113,7 +113,6 @@ void		swfdec_as_context_gc		(SwfdecAsCon
 void		swfdec_as_context_maybe_gc	(SwfdecAsContext *	context);
 
 void		swfdec_as_context_run		(SwfdecAsContext *	context);
-void		swfdec_as_context_return	(SwfdecAsContext *	context);
 void		swfdec_as_context_trace		(SwfdecAsContext *	context,
 						 const char *		string);
 
diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index c8013a4..f60876c 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -154,6 +154,25 @@ swfdec_as_frame_new_native (SwfdecAsCont
 }
 
 /**
+ * swfdec_as_frame_return:
+ * @frame: a #SwfdecAsFrame that is currently executing.
+ *
+ * Ends execution of the frame and instructs the frame's context to continue 
+ * execution with its parent frame. This function may only be called on the
+ * currently executing frame.
+ **/
+void
+swfdec_as_frame_return (SwfdecAsFrame *frame)
+{
+  SwfdecAsContext *context;
+  g_return_if_fail (SWFDEC_IS_AS_FRAME (frame));
+  context = SWFDEC_AS_OBJECT (frame)->context;
+  g_return_if_fail (frame == context->frame);
+
+  context->frame = frame->next;
+}
+
+/**
  * swfdec_as_frame_set_this:
  * @frame: a #SwfdecAsFrame
  * @thisp: object to use as the this object
diff --git a/libswfdec/swfdec_as_frame.h b/libswfdec/swfdec_as_frame.h
index 1473fa4..36756fb 100644
--- a/libswfdec/swfdec_as_frame.h
+++ b/libswfdec/swfdec_as_frame.h
@@ -71,6 +71,8 @@ GType		swfdec_as_frame_get_type	(void);
 SwfdecAsFrame *	swfdec_as_frame_new		(SwfdecAsContext *	context,
 						 SwfdecScript *		script);
 SwfdecAsFrame *	swfdec_as_frame_new_native	(SwfdecAsContext *	context);
+void		swfdec_as_frame_return		(SwfdecAsFrame *	frame);
+
 void		swfdec_as_frame_set_this	(SwfdecAsFrame *	frame,
 						 SwfdecAsObject *	thisp);
 void		swfdec_as_frame_preload		(SwfdecAsFrame *	frame);
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 5f5838e..396fa7b 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1556,12 +1556,10 @@ swfdec_action_define_function (SwfdecAsC
     SWFDEC_AS_VALUE_SET_OBJECT (swfdec_as_stack_push (frame->stack), SWFDEC_AS_OBJECT (fun));
   } else {
     SwfdecAsValue funval;
-    swfdec_as_object_root (SWFDEC_AS_OBJECT (fun));
     /* FIXME: really varobj? Not eval or sth like that? */
     function_name = swfdec_as_context_get_string (cx, function_name);
     SWFDEC_AS_VALUE_SET_OBJECT (&funval, SWFDEC_AS_OBJECT (fun));
     swfdec_as_object_set_variable (frame->target, function_name, &funval);
-    swfdec_as_object_unroot (SWFDEC_AS_OBJECT (fun));
   }
 
   /* update current context */
@@ -1685,7 +1683,7 @@ static void
 swfdec_action_return (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
   *cx->frame->return_value = *swfdec_as_stack_pop (cx->frame->stack);
-  swfdec_as_context_return (cx);
+  swfdec_as_frame_return (cx->frame);
 }
 
 static void
diff --git a/libswfdec/swfdec_as_number.c b/libswfdec/swfdec_as_number.c
index 63908ed..dec4599 100644
--- a/libswfdec/swfdec_as_number.c
+++ b/libswfdec/swfdec_as_number.c
@@ -62,9 +62,7 @@ swfdec_as_number_new (SwfdecAsContext *c
   
   SWFDEC_AS_VALUE_SET_NUMBER (&val, number);
   ret = swfdec_as_object_create (SWFDEC_AS_FUNCTION (context->Number), 1, &val, FALSE);
-  swfdec_as_object_root (ret);
   swfdec_as_context_run (context);
-  swfdec_as_object_unroot (ret);
   return ret;
 }
 
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index d2dabd1..339bf23 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -234,13 +234,11 @@ swfdec_as_object_new (SwfdecAsContext *c
   swfdec_as_object_add (object, context, sizeof (SwfdecAsObject));
   if (context->Object) {
     SwfdecAsValue val;
-    swfdec_as_object_root (object);
     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);
-    swfdec_as_object_unroot (object);
   }
   return object;
 }
@@ -289,24 +287,6 @@ swfdec_as_object_collect (SwfdecAsObject
 }
 
 void
-swfdec_as_object_root (SwfdecAsObject *object)
-{
-  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
-  g_return_if_fail ((object->flags & SWFDEC_AS_GC_ROOT) == 0);
-
-  object->flags |= SWFDEC_AS_GC_ROOT;
-}
-
-void
-swfdec_as_object_unroot (SwfdecAsObject *object)
-{
-  g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
-  g_return_if_fail ((object->flags & SWFDEC_AS_GC_ROOT) != 0);
-
-  object->flags &= ~SWFDEC_AS_GC_ROOT;
-}
-
-void
 swfdec_as_object_set_variable (SwfdecAsObject *object,
     const char *variable, const SwfdecAsValue *value)
 {
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 3ce58c5..8a51021 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -104,8 +104,6 @@ void		swfdec_as_object_add		(SwfdecAsObj
 						 SwfdecAsContext *    	context,
 						 gsize			size);
 void		swfdec_as_object_collect	(SwfdecAsObject *     	object);
-void		swfdec_as_object_root		(SwfdecAsObject *     	object);
-void		swfdec_as_object_unroot	  	(SwfdecAsObject *     	object);
 
 /* I'd like to name these [gs]et_property, but binding authors will complain
  * about overlap with g_object_[gs]et_property then */
diff-tree d8fb7ee0521b6fa84a3a9facb960e501b69212f2 (from 6ae6fc0a2a734d507ee49c837154f0c11ed10837)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat Jun 30 19:08:31 2007 +0100

    add documentation and remove unused swfdec_as_context_new ()
    
    You're supposed to subclass SwfdecAsContext. If you don't want to, you can still
    call g_object_new ().

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 0037932..49b4d38 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -105,6 +105,23 @@
 /*** GTK-DOC ***/
 
 /**
+ * SECTION:SwfdecAsContext
+ * @title: SwfdecAsContext
+ * @short_description: the main script engine context
+ * @see_also: SwfdecPlayer
+ *
+ * A #SwfdecAsContext provides the main execution environment for Actionscript
+ * execution. It provides the objects typically available in ECMAScript and
+ * manages script execution, garbage collection etc. #SwfdecPlayer is a
+ * subclass of the context that implements Flash specific objects on top of it.
+ * However, it is possible to use the context for completely different functions
+ * where a sandboxed scripting environment is needed. An example is the Swfdec 
+ * debugger.
+ * <note>The Actionscript engine is similar, but not equal to Javascript. It
+ * is not very different, but it is different.</note>
+ */
+
+/**
  * SwfdecAsContextState
  * @SWFDEC_AS_CONTEXT_NEW: the context is not yet initialized, 
  *                         swfdec_as_context_startup() needs to be called.
@@ -321,6 +338,15 @@ swfdec_as_context_do_mark (SwfdecAsConte
   g_hash_table_foreach (context->objects, swfdec_as_context_mark_roots, NULL);
 }
 
+/**
+ * swfdec_as_context_gc:
+ * @context: a #SwfdecAsContext
+ *
+ * Calls the Swfdec Gargbage collector and reclaims any unused memory. You 
+ * should call this function or swfdec_as_context_maybe_gc() regularly.
+ * <warning>Calling the GC during execution of code or initialization is not
+ *          allowed.</warning>
+ **/
 void
 swfdec_as_context_gc (SwfdecAsContext *context)
 {
@@ -328,7 +354,6 @@ swfdec_as_context_gc (SwfdecAsContext *c
 
   g_return_if_fail (SWFDEC_IS_AS_CONTEXT (context));
   g_return_if_fail (context->frame == NULL);
-  /* no GC during setup */
   g_return_if_fail (context->state != SWFDEC_AS_CONTEXT_NEW);
 
   SWFDEC_INFO ("invoking the garbage collector");
@@ -345,6 +370,15 @@ swfdec_as_context_needs_gc (SwfdecAsCont
   return context->memory_since_gc >= context->memory_until_gc;
 }
 
+/**
+ * swfdec_as_context_maybe_gc:
+ * @context: a #SwfdecAsContext
+ *
+ * Calls the garbage collector if necessary. It's a good idea to call this
+ * function regularly instead of swfdec_as_context_gc() as it only does collect
+ * garage as needed. For example, #SwfdecPlayer calls this function after every
+ * frame advancement.
+ **/
 void
 swfdec_as_context_maybe_gc (SwfdecAsContext *context)
 {
@@ -441,6 +475,17 @@ swfdec_as_context_create_string (SwfdecA
   return new + 1;
 }
 
+/**
+ * swfdec_as_context_get_string:
+ * @context: a #SwfdecAsContext
+ * @string: a sting that is not garbage-collected
+ *
+ * Gets the garbage-collected version of @string. You need to call this function
+ * for every not garbage-collected string that you want to use in Swfdecs script
+ * interpreter.
+ *
+ * Returns: the garbage-collected version of @string
+ **/
 const char *
 swfdec_as_context_get_string (SwfdecAsContext *context, const char *string)
 {
@@ -481,12 +526,6 @@ swfdec_as_context_give_string (SwfdecAsC
   return ret;
 }
 
-SwfdecAsContext *
-swfdec_as_context_new (void)
-{
-  return g_object_new (SWFDEC_TYPE_AS_CONTEXT, NULL);
-}
-
 /**
  * swfdec_as_context_get_time:
  * @context: a #SwfdecAsContext
@@ -511,6 +550,18 @@ swfdec_as_context_get_time (SwfdecAsCont
     g_get_current_time (tv);
 }
 
+/**
+ * swfdec_as_context_run:
+ * @context: a #SwfdecAsContext
+ *
+ * Continues running the script engine. Executing code in this engine works
+ * in 2 steps: First, you push the frame to be executed onto the stack, then
+ * you call this function to execute it. So this function is the single entry
+ * point to script execution. This might be helpful when debugging your 
+ * application. 
+ * <note>A lot of convenience functions like swfdec_as_object_run() call this 
+ * function automatically.</note>
+ **/
 void
 swfdec_as_context_run (SwfdecAsContext *context)
 {
@@ -673,6 +724,13 @@ swfdec_as_context_return (SwfdecAsContex
   context->frame = context->frame->next;
 }
 
+/**
+ * swfdec_as_context_trace:
+ * @context: a #SwfdecAsContext
+ * @string: a string to output
+ *
+ * Causes the emission of the trace signal with the provided @string.
+ **/
 void
 swfdec_as_context_trace (SwfdecAsContext *context, const char *string)
 {
diff --git a/libswfdec/swfdec_as_context.h b/libswfdec/swfdec_as_context.h
index ae625a9..37c5251 100644
--- a/libswfdec/swfdec_as_context.h
+++ b/libswfdec/swfdec_as_context.h
@@ -89,7 +89,6 @@ struct _SwfdecAsContextClass {
 
 GType		swfdec_as_context_get_type	(void);
 
-SwfdecAsContext *swfdec_as_context_new		(void);
 void		swfdec_as_context_startup     	(SwfdecAsContext *	context,
 						 guint			version);
 
diff-tree 6ae6fc0a2a734d507ee49c837154f0c11ed10837 (from 173401debdee58e1811cb556c79da1d3cd61b094)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Jun 29 16:53:09 2007 +0100

    optionally allow trace to use thread pools for multithreaded checking
    
    This is not enabled by default, since it can cause various issues.
    The most important one:
    foo_get_type() functions (defined with G_DEFINE_TYPE) are not threadsafe.
    This can lead to crashes.

diff --git a/configure.ac b/configure.ac
index 4d1b2ba..a6a5751 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,6 +79,12 @@ fi
 AC_SUBST(GLIB_LIBS)
 AC_SUBST(GLIB_CFLAGS)
 AC_SUBST(GLIB_VER)
+dnl we detect gthread seperately for now, since we don't want to link libswfdec to it (yet)
+PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= $GLIB_VER,
+		HAVE_GLIB=yes, HAVE_GLIB=no)
+if test "$HAVE_GTHREAD" = "no"; then
+  AC_MSG_ERROR([gthread-2.0 >= $GLIB_VER is required to build swfdec])
+fi
 dnl FIXME: detect these executables correctly
 GLIB_GENMARSHAL=glib-genmarshal
 AC_SUBST(GLIB_GENMARSHAL)
diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index e06d866..930a5d8 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -9,8 +9,8 @@ trace_SOURCES = \
 noinst_HEADERS = \
 	swfdec_interaction.h
 
-trace_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS)
-trace_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS)
+trace_CFLAGS = $(GLOBAL_CFLAGS) $(SWFDEC_CFLAGS) $(CAIRO_CFLAGS) $(GTHREAD_CFLAGS)
+trace_LDFLAGS = $(SWFDEC_LIBS) $(CAIRO_LIBS) $(GTHREAD_LIBS)
 
 EXTRA_DIST = \
 	README \
diff --git a/test/trace/trace.c b/test/trace/trace.c
index acb5bed..864090a 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -31,6 +31,8 @@ struct _Test {
   char *	filename;		/* name of the file to be tested */
   char *	output;			/* test result */
   gboolean	success;		/* TRUE if test was successful, FALSE on error */
+  GMutex *	mutex;			/* NULL or mutex for protecting output */
+  GCond *	cond;			/* NULL or cond to signal after setting output */
 };
 
 static Test *
@@ -77,8 +79,9 @@ fscommand_cb (SwfdecPlayer *player, cons
 }
 
 static void
-run_test (Test *test)
+run_test (gpointer testp, gpointer unused)
 {
+  Test *test = testp;
   SwfdecLoader *loader;
   SwfdecPlayer *player;
   SwfdecBuffer *buffer;
@@ -179,17 +182,27 @@ run_test (Test *test)
   g_string_append (output, "  OK\n");
   test->success = TRUE;
 fail:
+  if (test->mutex)
+    g_mutex_lock (test->mutex);
   test->output = g_string_free (output, FALSE);
+  if (test->mutex) {
+    g_cond_signal (test->cond);
+    g_mutex_unlock (test->mutex);
+  }
 }
 
 int
 main (int argc, char **argv)
 {
   GList *walk, *tests = NULL;
-  GString *failed_tests = g_string_new ("");
+  GString *failed_tests;
   guint failures = 0;
+  GThreadPool *pool;
+  GError *error = NULL;
 
+  g_thread_init (NULL);
   swfdec_init ();
+  failed_tests = g_string_new ("");
 
   /* collect all tests into the tests list */
   if (argc > 1) {
@@ -219,18 +232,63 @@ main (int argc, char **argv)
   tests = g_list_sort (tests, test_compare);
 
   /* run them and put failed ones in failed_tests */
-  for (walk = tests; walk; walk = walk->next) {
-    Test *test = walk->data;
-    
-    run_test (test);
-    g_print (test->output);
-    if (!test->success) {
-      failures++;
-      g_string_append_printf (failed_tests, 
-	  "          %s\n", test->filename);
+  if (g_getenv ("SWFDEC_TEST_THREADS")) {
+    pool = g_thread_pool_new (run_test, NULL, -1, FALSE, &error);
+    if (pool == NULL) {
+      g_print ("  WARNING: Could not start thread pool: %s\n", error->message);
+      g_print ("  WARNING: testing unthreaded\n");
+      g_error_free (error);
+      error = NULL;
+    }
+  } else {
+    pool = NULL;
+  }
+  if (pool == NULL) {
+    for (walk = tests; walk; walk = walk->next) {
+      Test *test = walk->data;
+      
+      run_test (test, NULL);
+      g_print (test->output);
+      if (!test->success) {
+	failures++;
+	g_string_append_printf (failed_tests, 
+	    "          %s\n", test->filename);
+      }
+      test_free (test);
+    }
+  } else {
+    GMutex *mutex = g_mutex_new ();
+    GCond *cond = g_cond_new ();
+    for (walk = tests; walk; walk = walk->next) {
+      Test *test = walk->data;
+      test->mutex = mutex;
+      test->cond = cond;
+      g_thread_pool_push (pool, test, &error);
+      if (error) {
+	/* huh? */
+	g_assert_not_reached ();
+	g_error_free (error);
+	error = NULL;
+      }
+    }
+    g_mutex_lock (mutex);
+    for (walk = tests; walk; walk = walk->next) {
+      Test *test = walk->data;
+      while (test->output == NULL)
+	g_cond_wait (cond, mutex);
+      g_print (test->output);
+      if (!test->success) {
+	failures++;
+	g_string_append_printf (failed_tests, 
+	    "          %s\n", test->filename);
+      }
+      test_free (test);
     }
-    test_free (test);
+    g_mutex_unlock (mutex);
+    g_cond_free (cond);
+    g_mutex_free (mutex);
   }
+  g_list_free (tests);
 
   /* report failures and exit */
   if (failures > 0) {
diff-tree 173401debdee58e1811cb556c79da1d3cd61b094 (from 6367dac34114e42feca8c64321b31a68a408c888)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Jun 29 14:21:19 2007 +0100

    clean up test-running
    
    - create a Test structure for every test
    - sort all the Test structures
    - make the test runner modify the Test structure instead of providing return values

diff --git a/test/trace/trace.c b/test/trace/trace.c
index 8416db2..acb5bed 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -21,10 +21,45 @@
 #include "config.h"
 #endif
 #include <math.h>
+#include <stdlib.h>
 #include <string.h>
 #include <libswfdec/swfdec.h>
 #include "swfdec_interaction.h"
 
+typedef struct _Test Test;
+struct _Test {
+  char *	filename;		/* name of the file to be tested */
+  char *	output;			/* test result */
+  gboolean	success;		/* TRUE if test was successful, FALSE on error */
+};
+
+static Test *
+test_new (char *filename)
+{
+  Test *test;
+
+  test = g_slice_new0 (Test);
+  test->filename = filename;
+  return test;
+}
+
+static void
+test_free (Test *test)
+{
+  g_free (test->filename);
+  g_free (test->output);
+  g_slice_free (Test, test);
+}
+
+static int
+test_compare (gconstpointer a, gconstpointer b)
+{
+  const Test *ta = (const Test *) a;
+  const Test *tb = (const Test *) b;
+
+  return strcmp (ta->filename, tb->filename);
+}
+
 static void
 trace_cb (SwfdecPlayer *player, const char *message, GString *string)
 {
@@ -41,8 +76,8 @@ fscommand_cb (SwfdecPlayer *player, cons
   }
 }
 
-static gboolean
-run_test (const char *filename)
+static void
+run_test (Test *test)
 {
   SwfdecLoader *loader;
   SwfdecPlayer *player;
@@ -55,8 +90,8 @@ run_test (const char *filename)
   SwfdecInteraction *inter;
 
   output = g_string_new ("");
-  g_string_append_printf (output, "Testing %s:\n", filename);
-  loader = swfdec_loader_new_from_file (filename);
+  g_string_append_printf (output, "Testing %s:\n", test->filename);
+  loader = swfdec_loader_new_from_file (test->filename);
   if (loader->error) {
     g_string_append_printf (output, "  ERROR: %s\n", loader->error);
     goto fail;
@@ -71,7 +106,7 @@ run_test (const char *filename)
     g_object_unref (player);
     goto fail;
   }
-  str = g_strdup_printf ("%s.act", filename);
+  str = g_strdup_printf ("%s.act", test->filename);
   if (g_file_test (str, G_FILE_TEST_EXISTS)) {
     inter = swfdec_interaction_new_from_file (str, &error);
     if (inter == NULL) {
@@ -108,7 +143,7 @@ run_test (const char *filename)
   g_signal_handlers_disconnect_by_func (player, trace_cb, string);
   g_object_unref (player);
 
-  str = g_strdup_printf ("%s.trace", filename);
+  str = g_strdup_printf ("%s.trace", test->filename);
   buffer = swfdec_buffer_new_from_file (str, &error);
   if (buffer == NULL) {
     g_string_append_printf (output, "  ERROR: %s\n", error->message);
@@ -142,28 +177,25 @@ run_test (const char *filename)
   g_string_free (string, TRUE);
   swfdec_buffer_unref (buffer);
   g_string_append (output, "  OK\n");
-  g_print ("%s", output->str);
-  g_string_free (output, TRUE);
-  return TRUE;
-
+  test->success = TRUE;
 fail:
-  g_print ("%s", output->str);
-  g_string_free (output, FALSE);
-  return TRUE;
+  test->output = g_string_free (output, FALSE);
 }
 
 int
 main (int argc, char **argv)
 {
-  GList *failed_tests = NULL;
+  GList *walk, *tests = NULL;
+  GString *failed_tests = g_string_new ("");
+  guint failures = 0;
 
   swfdec_init ();
 
+  /* collect all tests into the tests list */
   if (argc > 1) {
     int i;
     for (i = 1; i < argc; i++) {
-      if (!run_test (argv[i]))
-	failed_tests = g_list_prepend (failed_tests, g_strdup (argv[i]));;
+      tests = g_list_append (tests, test_new (g_strdup (argv[i])));
     }
   } else {
     GDir *dir;
@@ -178,28 +210,38 @@ main (int argc, char **argv)
       if (!g_str_has_suffix (file, ".swf"))
 	continue;
       name = g_build_filename (path, file, NULL);
-      if (!run_test (name)) {
-	failed_tests = g_list_prepend (failed_tests, name);
-      } else {
-	g_free (name);
-      }
+      tests = g_list_append (tests, test_new (name));
     }
     g_dir_close (dir);
   }
 
-  if (failed_tests) {
-    GList *walk;
-    failed_tests = g_list_sort (failed_tests, (GCompareFunc) strcmp);
-    g_print ("\nFAILURES: %u\n", g_list_length (failed_tests));
-    for (walk = failed_tests; walk; walk = walk->next) {
-      g_print ("          %s\n", (char *) walk->data);
-      g_free (walk->data);
-    }
-    g_list_free (failed_tests);
-    return 1;
+  /* sort the tests by filename */
+  tests = g_list_sort (tests, test_compare);
+
+  /* run them and put failed ones in failed_tests */
+  for (walk = tests; walk; walk = walk->next) {
+    Test *test = walk->data;
+    
+    run_test (test);
+    g_print (test->output);
+    if (!test->success) {
+      failures++;
+      g_string_append_printf (failed_tests, 
+	  "          %s\n", test->filename);
+    }
+    test_free (test);
+  }
+
+  /* report failures and exit */
+  if (failures > 0) {
+    g_print ("\nFAILURES: %u\n", failures);
+    g_print ("%s", failed_tests->str);
+    g_string_free (failed_tests, TRUE);
+    return EXIT_FAILURE;
   } else {
     g_print ("\nEVERYTHING OK\n");
-    return 0;
+    g_string_free (failed_tests, TRUE);
+    return EXIT_SUCCESS;
   }
 }
 
diff-tree 6367dac34114e42feca8c64321b31a68a408c888 (from 13e02b69bbd5b3681a6a396d5279fdaa6e9a5059)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Jun 29 14:56:47 2007 +0200

    capture all output of a test in a GString instead of g_print'ing it step-by-step

diff --git a/test/trace/trace.c b/test/trace/trace.c
index 47775a2..8416db2 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -49,16 +49,17 @@ run_test (const char *filename)
   SwfdecBuffer *buffer;
   guint time_left;
   char *str;
-  GString *string;
+  GString *string, *output;
   GError *error = NULL;
   gboolean quit = FALSE;
   SwfdecInteraction *inter;
 
-  g_print ("Testing %s:\n", filename);
+  output = g_string_new ("");
+  g_string_append_printf (output, "Testing %s:\n", filename);
   loader = swfdec_loader_new_from_file (filename);
   if (loader->error) {
-    g_print ("  ERROR: %s\n", loader->error);
-    return FALSE;
+    g_string_append_printf (output, "  ERROR: %s\n", loader->error);
+    goto fail;
   }
   string = g_string_new ("");
   player = swfdec_player_new ();
@@ -66,19 +67,19 @@ run_test (const char *filename)
   g_signal_connect (player, "fscommand", G_CALLBACK (fscommand_cb), &quit);
   swfdec_player_set_loader (player, loader);
   if (!swfdec_player_is_initialized (player)) {
-    g_print ("  ERROR: player is not initialized\n");
+    g_string_append_printf (output, "  ERROR: player is not initialized\n");
     g_object_unref (player);
-    return FALSE;
+    goto fail;
   }
   str = g_strdup_printf ("%s.act", filename);
   if (g_file_test (str, G_FILE_TEST_EXISTS)) {
     inter = swfdec_interaction_new_from_file (str, &error);
     if (inter == NULL) {
-      g_print ("  ERROR: %s\n", error->message);
+      g_string_append_printf (output, "  ERROR: %s\n", error->message);
       g_object_unref (player);
       g_error_free (error);
       g_free (str);
-      return FALSE;
+      goto fail;
     }
     time_left = swfdec_interaction_get_duration (inter);
   } else {
@@ -110,35 +111,44 @@ run_test (const char *filename)
   str = g_strdup_printf ("%s.trace", filename);
   buffer = swfdec_buffer_new_from_file (str, &error);
   if (buffer == NULL) {
-    g_print ("  ERROR: %s\n", error->message);
+    g_string_append_printf (output, "  ERROR: %s\n", error->message);
     g_error_free (error);
     g_string_free (string, TRUE);
     g_free (str);
-    return FALSE;
+    goto fail;
   }
   if (string->len != buffer->length ||
       memcmp (buffer->data, string->str, buffer->length) != 0) {
-    g_print ("  ERROR: unexpected trace output\n");
+    g_string_append (output, "  ERROR: unexpected trace output\n");
     if (g_file_set_contents ("tmp", string->str, string->len, NULL)) {
       char *command[] = { "diff", "-u", (char *) str, "tmp", NULL };
       char *result;
       if (!g_spawn_sync (NULL, command, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
 	  &result, NULL, NULL, &error)) {
-	g_printerr ("  Couldn't spawn diff to compare the results: %s\n", error->message);
+	g_string_append_printf (output, 
+	    "  ERROR: Could not spawn diff to compare the results: %s\n", 
+	    error->message);
 	g_error_free (error);
       } else {
-	g_print ("%s", result);
+	g_string_append (output, result);
       }
     }
     g_string_free (string, TRUE);
     swfdec_buffer_unref (buffer);
     g_free (str);
-    return FALSE;
+    goto fail;
   }
   g_free (str);
   g_string_free (string, TRUE);
   swfdec_buffer_unref (buffer);
-  g_print ("  OK\n");
+  g_string_append (output, "  OK\n");
+  g_print ("%s", output->str);
+  g_string_free (output, TRUE);
+  return TRUE;
+
+fail:
+  g_print ("%s", output->str);
+  g_string_free (output, FALSE);
   return TRUE;
 }
 
diff-tree 13e02b69bbd5b3681a6a396d5279fdaa6e9a5059 (from 2203783339a0ece4ce8d264d0ec28c77034c3288)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Jun 29 14:50:37 2007 +0200

    capture diff output and then g_print it instead of letting diff print to stdout
    
    This allows better control about what g_print does.

diff --git a/test/trace/trace.c b/test/trace/trace.c
index 5041641..47775a2 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -121,10 +121,13 @@ run_test (const char *filename)
     g_print ("  ERROR: unexpected trace output\n");
     if (g_file_set_contents ("tmp", string->str, string->len, NULL)) {
       char *command[] = { "diff", "-u", (char *) str, "tmp", NULL };
+      char *result;
       if (!g_spawn_sync (NULL, command, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
-	  NULL, NULL, NULL, &error)) {
+	  &result, NULL, NULL, &error)) {
 	g_printerr ("  Couldn't spawn diff to compare the results: %s\n", error->message);
 	g_error_free (error);
+      } else {
+	g_print ("%s", result);
       }
     }
     g_string_free (string, TRUE);


More information about the Swfdec mailing list