[Swfdec] Branch 'vivi' - 60 commits - libswfdec-gtk/swfdec_gtk_loader.c libswfdec/Makefile.am libswfdec/swfdec_as_array.c libswfdec/swfdec_as_context.c libswfdec/swfdec_as_frame.c libswfdec/swfdec_as_frame_internal.h libswfdec/swfdec_as_interpret.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_object.h libswfdec/swfdec_as_string.c libswfdec/swfdec_as_string.h libswfdec/swfdec_as_strings.c libswfdec/swfdec_as_super.c libswfdec/swfdec_as_types.c libswfdec/swfdec_as_with.c libswfdec/swfdec_codec_screen.c libswfdec/swfdec_flv_decoder.c libswfdec/swfdec_initialize.as libswfdec/swfdec_initialize.h libswfdec/swfdec_load_object_as.c libswfdec/swfdec_load_object_as.h libswfdec/swfdec_load_object.c libswfdec/swfdec_load_object.h libswfdec/swfdec_loadvars_as.c libswfdec/swfdec_movie.c libswfdec/swfdec_player_as.c libswfdec/swfdec_player.c libswfdec/swfdec_player_internal.h libswfdec/swfdec_sprite_movie_as.c libswfdec/swfdec_sprite_movie.c libswfdec/swfdec_video_movie.c libswfdec/swfdec_xml_as.c libswfdec/swfdec_xml_as.h libswfdec/swfdec_xml.c libswfdec/swfdec_xml.h test/trace vivified/core

Benjamin Otte company at kemper.freedesktop.org
Mon Aug 20 09:17:46 PDT 2007


 libswfdec-gtk/swfdec_gtk_loader.c             |   57 ++++--
 libswfdec/Makefile.am                         |    8 
 libswfdec/swfdec_as_array.c                   |    9 -
 libswfdec/swfdec_as_context.c                 |   42 ++--
 libswfdec/swfdec_as_frame.c                   |   14 -
 libswfdec/swfdec_as_frame_internal.h          |    3 
 libswfdec/swfdec_as_interpret.c               |   44 +++-
 libswfdec/swfdec_as_object.c                  |  129 ++++++++------
 libswfdec/swfdec_as_object.h                  |   29 ++-
 libswfdec/swfdec_as_string.c                  |   73 ++++----
 libswfdec/swfdec_as_string.h                  |    1 
 libswfdec/swfdec_as_strings.c                 |    3 
 libswfdec/swfdec_as_super.c                   |    6 
 libswfdec/swfdec_as_types.c                   |    5 
 libswfdec/swfdec_as_with.c                    |    6 
 libswfdec/swfdec_codec_screen.c               |    1 
 libswfdec/swfdec_flv_decoder.c                |    1 
 libswfdec/swfdec_initialize.as                |   45 +++++
 libswfdec/swfdec_initialize.h                 |  163 +++++++++++-------
 libswfdec/swfdec_load_object.c                |  230 ++++++++++++++++++++++++++
 libswfdec/swfdec_load_object.h                |   35 +--
 libswfdec/swfdec_load_object_as.c             |   48 +++++
 libswfdec/swfdec_load_object_as.h             |   31 +++
 libswfdec/swfdec_loadvars_as.c                |   70 +++++++
 libswfdec/swfdec_movie.c                      |    6 
 libswfdec/swfdec_player.c                     |   10 -
 libswfdec/swfdec_player_as.c                  |    8 
 libswfdec/swfdec_player_internal.h            |    1 
 libswfdec/swfdec_sprite_movie.c               |    2 
 libswfdec/swfdec_sprite_movie_as.c            |   25 ++
 libswfdec/swfdec_video_movie.c                |    2 
 libswfdec/swfdec_xml.c                        |  177 --------------------
 libswfdec/swfdec_xml_as.c                     |   17 +
 libswfdec/swfdec_xml_as.h                     |   14 -
 test/trace/Makefile.am                        |   48 +++++
 test/trace/addProperty-flags-5.swf            |binary
 test/trace/addProperty-flags-5.swf.trace      |    6 
 test/trace/addProperty-flags-6.swf            |binary
 test/trace/addProperty-flags-6.swf.trace      |    8 
 test/trace/addProperty-flags-7.swf            |binary
 test/trace/addProperty-flags-7.swf.trace      |    8 
 test/trace/addProperty-flags-8.swf            |binary
 test/trace/addProperty-flags-8.swf.trace      |    8 
 test/trace/addProperty-flags.as               |   23 ++
 test/trace/construct-constructors-5.swf       |binary
 test/trace/construct-constructors-5.swf.trace |    5 
 test/trace/construct-constructors-6.swf       |binary
 test/trace/construct-constructors-6.swf.trace |    7 
 test/trace/construct-constructors-7.swf       |binary
 test/trace/construct-constructors-7.swf.trace |    7 
 test/trace/construct-constructors-8.swf       |binary
 test/trace/construct-constructors-8.swf.trace |    7 
 test/trace/construct-constructors.as          |   20 ++
 test/trace/construct-properties-5.swf         |binary
 test/trace/construct-properties-5.swf.trace   |   93 ++++++++++
 test/trace/construct-properties-6.swf         |binary
 test/trace/construct-properties-6.swf.trace   |   93 ++++++++++
 test/trace/construct-properties-7.swf         |binary
 test/trace/construct-properties-7.swf.trace   |   93 ++++++++++
 test/trace/construct-properties-8.swf         |binary
 test/trace/construct-properties-8.swf.trace   |   93 ++++++++++
 test/trace/construct-properties.as            |   36 ++++
 test/trace/forin-delete-5.swf                 |binary
 test/trace/forin-delete-5.swf.trace           |    1 
 test/trace/forin-delete-6.swf                 |binary
 test/trace/forin-delete-6.swf.trace           |    1 
 test/trace/forin-delete-7.swf                 |binary
 test/trace/forin-delete-7.swf.trace           |    1 
 test/trace/forin-delete.as                    |   14 +
 test/trace/loadobject-5.swf                   |binary
 test/trace/loadobject-5.swf.trace             |   57 ++++++
 test/trace/loadobject-6.swf                   |binary
 test/trace/loadobject-6.swf.trace             |   57 ++++++
 test/trace/loadobject-7.swf                   |binary
 test/trace/loadobject-7.swf.trace             |   57 ++++++
 test/trace/loadobject.as                      |   34 +++
 test/trace/loadvars-5.swf                     |binary
 test/trace/loadvars-5.swf.trace               |    2 
 test/trace/loadvars-6.swf                     |binary
 test/trace/loadvars-6.swf.trace               |   51 +++++
 test/trace/loadvars-7.swf                     |binary
 test/trace/loadvars-7.swf.trace               |   51 +++++
 test/trace/loadvars.as                        |   39 ++++
 test/trace/loadvars.txt                       |    3 
 test/trace/propflags-5.swf                    |binary
 test/trace/propflags-5.swf.trace              |   11 +
 test/trace/propflags-6.swf                    |binary
 test/trace/propflags-6.swf.trace              |   11 +
 test/trace/propflags-7.swf                    |binary
 test/trace/propflags-7.swf.trace              |   10 +
 test/trace/propflags.as                       |   14 +
 test/trace/trace.c                            |    3 
 test/trace/trace_properties.as                |  147 ++++++++++++++++
 vivified/core/vivi_breakpoint.c               |   19 +-
 vivified/core/vivi_wrap.c                     |    2 
 95 files changed, 2001 insertions(+), 454 deletions(-)

New commits:
diff-tree e04f9526fa8a613d88219ebcb47ac61addd5bcab (from parents)
Merge: 2f123ef946932f1b5e684b90fd27a056c0ea98f6 da9fc3e76d3757cb3a8a4459802c753adbbbcbe7
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 18:17:37 2007 +0200

    Merge branch 'master' into vivi
    
    Conflicts:
    
    	libswfdec/swfdec_as_context.c
    	libswfdec/swfdec_as_interpret.c
    	test/trace/trace.c
    
    Also updated API in vivified code to changed APIs from master

diff --cc libswfdec/swfdec_as_context.c
index b2a74cb,4975822..0cb0226
@@@ -419,7 -419,7 +419,8 @@@
  
  enum {
    PROP_0,
 +  PROP_DEBUGGER,
+   PROP_UNTIL_GC
  };
  
  G_DEFINE_TYPE (SwfdecAsContext, swfdec_as_context, G_TYPE_OBJECT)
@@@ -430,11 -430,11 +431,15 @@@
      GParamSpec * pspec)
  {
    SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
 +
+   
    switch (param_id) {
 +    case PROP_DEBUGGER:
 +      g_value_set_object (value, context->debugger);
 +      break;
+     case PROP_UNTIL_GC:
+       g_value_set_ulong (value, (gulong) context->memory_until_gc);
+       break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
        break;
@@@ -446,11 -446,11 +451,15 @@@
      GParamSpec * pspec)
  {
    SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
 +
+   
    switch (param_id) {
 +    case PROP_DEBUGGER:
 +      context->debugger = g_value_dup_object (value);
 +      break;
+     case PROP_UNTIL_GC:
+       context->memory_until_gc = g_value_get_ulong (value);
+       break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
        break;
@@@ -489,9 -485,10 +498,13 @@@
    object_class->get_property = swfdec_as_context_get_property;
    object_class->set_property = swfdec_as_context_set_property;
  
 +  g_object_class_install_property (object_class, PROP_DEBUGGER,
 +      g_param_spec_object ("debugger", "debugger", "debugger used in this player",
 +	  SWFDEC_TYPE_AS_DEBUGGER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+   g_object_class_install_property (object_class, PROP_UNTIL_GC,
+       g_param_spec_ulong ("memory-until-gc", "memory until gc", 
+ 	  "amount of bytes that need to be allocated before garbage collection triggers",
+ 	  0, G_MAXULONG, 8 * 1024 * 1024, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
  
    /**
     * SwfdecAsContext::trace:
diff --cc libswfdec/swfdec_as_interpret.c
index 461c875,4a712c2..d08b00a
@@@ -1541,7 -1554,8 +1542,8 @@@
    }
    if (name == NULL)
      name = "unnamed_function";
 -  script = swfdec_script_new (&bits, name, cx->version);
 +  script = swfdec_script_new_from_bits (&bits, name, cx->version);
+   swfdec_buffer_unref (buffer);
    if (script == NULL) {
      SWFDEC_ERROR ("failed to create script");
      g_free (args);
diff --cc libswfdec/swfdec_as_object.c
index 111dbb3,83ad4cf..d041803
@@@ -562,14 -577,8 +577,14 @@@
    g_return_if_fail (variable != NULL);
    g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
  
 +  if (object->context->debugger) {
 +    SwfdecAsDebugger *debugger = object->context->debugger;
 +    SwfdecAsDebuggerClass *dklass = SWFDEC_AS_DEBUGGER_GET_CLASS (debugger);
 +    if (dklass->set_variable)
 +      dklass->set_variable (debugger, object->context, object, variable, value);
 +  }
    klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
-   klass->set (object, variable, value);
+   klass->set (object, variable, value, default_flags);
  }
  
  /**
diff --cc test/trace/trace.c
index cc788db,af52ef6..55f1754
@@@ -100,7 -100,8 +100,8 @@@
      goto fail;
    }
    string = g_string_new ("");
 -  player = swfdec_player_new ();
 +  player = swfdec_player_new (NULL);
+   g_object_set (player, "memory-until-gc", (gulong) 0, NULL);
    g_signal_connect (player, "trace", G_CALLBACK (trace_cb), string);
    g_signal_connect (player, "fscommand", G_CALLBACK (fscommand_cb), &quit);
    swfdec_player_set_loader (player, loader);
diff --cc vivified/core/vivi_breakpoint.c
index 15cfc26,0000000..11ae4bf
mode 100644,000000..100644
@@@ -1,236 -1,0 +1,241 @@@
 +/* Vivified
 + * 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 "vivi_breakpoint.h"
 +#include "vivi_application.h"
 +#include "vivi_function.h"
 +#include "vivi_wrap.h"
 +
 +G_DEFINE_TYPE (ViviBreakpoint, vivi_breakpoint, SWFDEC_TYPE_AS_OBJECT)
 +
 +static gboolean
 +vivi_breakpoint_step (ViviDebugger *debugger, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue retval;
 +
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onCommand"), 0, NULL, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static gboolean
 +vivi_breakpoint_start_frame (ViviDebugger *debugger, SwfdecAsFrame *frame, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue val;
 +  SwfdecAsValue retval;
 +
 +  SWFDEC_AS_VALUE_SET_OBJECT (&val, vivi_wrap_object (VIVI_APPLICATION (obj->context), SWFDEC_AS_OBJECT (frame)));
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStartFrame"), 1, &val, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static gboolean
 +vivi_breakpoint_finish_frame (ViviDebugger *debugger, SwfdecAsFrame *frame, const SwfdecAsValue *ret, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue vals[2];
 +  SwfdecAsValue retval;
 +
 +  SWFDEC_AS_VALUE_SET_OBJECT (&vals[0], vivi_wrap_object (VIVI_APPLICATION (obj->context), SWFDEC_AS_OBJECT (frame)));
 +  vivi_wrap_value (VIVI_APPLICATION (obj->context), &vals[1], ret);
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onStartFrame"), 2, vals, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static gboolean
 +vivi_breakpoint_set_variable (ViviDebugger *debugger, SwfdecAsObject *object, 
 +    const char *variable, const SwfdecAsValue *value, ViviBreakpoint *breakpoint)
 +{
 +  SwfdecAsObject *obj = SWFDEC_AS_OBJECT (breakpoint);
 +  SwfdecAsValue vals[3];
 +  SwfdecAsValue retval;
 +
 +  SWFDEC_AS_VALUE_SET_OBJECT (&vals[0], vivi_wrap_object (VIVI_APPLICATION (obj->context), object));
 +  SWFDEC_AS_VALUE_SET_STRING (&vals[1], swfdec_as_context_get_string (obj->context, variable));
 +  vivi_wrap_value (VIVI_APPLICATION (obj->context), &vals[2], value);
 +  swfdec_as_object_call (obj, swfdec_as_context_get_string (obj->context, "onSetVariable"), 3, vals, &retval);
 +  return swfdec_as_value_to_boolean (obj->context, &retval);
 +}
 +
 +static const struct {
 +  const char *	event;
 +  const char *	signal;
 +  GCallback	handler;
 +} events[] = {
 +  { NULL, NULL, NULL }, /* invalid */
 +  { "onCommand", "step", G_CALLBACK (vivi_breakpoint_step) },
 +  { "onStartFrame", "start-frame", G_CALLBACK (vivi_breakpoint_start_frame) },
 +  { "onExitFrame", "finish-frame", G_CALLBACK (vivi_breakpoint_finish_frame) },
 +  { "onSetVariable", "set-variable", G_CALLBACK (vivi_breakpoint_set_variable) }
 +};
 +
 +static guint
 +vivi_breakpoint_find_event (const char *name)
 +{
 +  guint i;
 +
 +  for (i = 1; i < G_N_ELEMENTS (events); i++) {
 +    if (g_str_equal (events[i].event, name))
 +      return i;
 +  }
 +  return 0;
 +}
 +
 +static void
 +vivi_breakpoint_add (ViviBreakpoint *breakpoint, guint i)
 +{
 +  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
 +
 +  g_assert (i != 0);
 +  if (breakpoint->active) {
 +    breakpoint->handlers[i] = g_signal_connect (debugger, events[i].signal,
 +	events[i].handler, breakpoint);
 +  } else {
 +    breakpoint->handlers[i] = 1;
 +  }
 +}
 +
 +static void
 +vivi_breakpoint_remove (ViviBreakpoint *breakpoint, guint i)
 +{
 +  ViviDebugger *debugger = VIVI_APPLICATION (SWFDEC_AS_OBJECT (breakpoint)->context)->debugger;
 +
 +  g_assert (i != 0);
 +  if (breakpoint->active)
 +    g_signal_handler_disconnect (debugger, breakpoint->handlers[i]);
 +  breakpoint->handlers[i] = 0;
 +}
 +
 +static void
- vivi_breakpoint_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val)
++vivi_breakpoint_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val, guint flags)
 +{
 +  guint i;
 +
 +  i = vivi_breakpoint_find_event (variable);
 +  if (i) {
 +    ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
 +    if (SWFDEC_AS_VALUE_IS_OBJECT (val) &&
 +	SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (val))) {
 +      if (!breakpoint->handlers[i])
 +	vivi_breakpoint_add (breakpoint, i);
 +    } else {
 +      if (breakpoint->handlers[i])
 +	vivi_breakpoint_remove (breakpoint, i);
 +    }
 +  }
-   SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->set (object, variable, val);
++  SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->set (object, variable, val, flags);
 +}
 +
- static gboolean
++static SwfdecAsDeleteReturn
 +vivi_breakpoint_delete (SwfdecAsObject *object, const char *variable)
 +{
 +  ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
 +  guint i;
++  SwfdecAsDeleteReturn ret;
 +
-   i = vivi_breakpoint_find_event (variable);
-   if (i && breakpoint->handlers[i])
-     vivi_breakpoint_remove (breakpoint, i);
++  ret = SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->del (object, variable);
++
++  if (ret == SWFDEC_AS_DELETE_DELETED) {
++    i = vivi_breakpoint_find_event (variable);
++    if (i && breakpoint->handlers[i])
++      vivi_breakpoint_remove (breakpoint, i);
++  }
 +
-   return SWFDEC_AS_OBJECT_CLASS (vivi_breakpoint_parent_class)->del (object, variable);
++  return ret;
 +}
 +
 +static void
 +vivi_breakpoint_dispose (GObject *object)
 +{
 +  ViviBreakpoint *breakpoint = VIVI_BREAKPOINT (object);
 +
 +  vivi_breakpoint_set_active (breakpoint, FALSE);
 +
 +  G_OBJECT_CLASS (vivi_breakpoint_parent_class)->dispose (object);
 +}
 +
 +static void
 +vivi_breakpoint_class_init (ViviBreakpointClass *klass)
 +{
 +  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 +  SwfdecAsObjectClass *as_object_class = SWFDEC_AS_OBJECT_CLASS (klass);
 +
 +  object_class->dispose = vivi_breakpoint_dispose;
 +
 +  as_object_class->set = vivi_breakpoint_set;
 +  as_object_class->del = vivi_breakpoint_delete;
 +}
 +
 +static void
 +vivi_breakpoint_init (ViviBreakpoint *breakpoint)
 +{
 +  breakpoint->active = TRUE;
 +}
 +
 +void
 +vivi_breakpoint_set_active (ViviBreakpoint *breakpoint, gboolean active)
 +{
 +  guint i;
 +
 +  g_return_if_fail (VIVI_IS_BREAKPOINT (breakpoint));
 +
 +  g_print ("active = %d", active);
 +  if (breakpoint->active == active)
 +    return;
 +  breakpoint->active = !breakpoint->active;
 +  for (i = 1; i < G_N_ELEMENTS (events); i++) {
 +    if (breakpoint->handlers[i] == 0)
 +      continue;
 +    /* FIXME: this is hacky */
 +    breakpoint->active = !breakpoint->active;
 +    vivi_breakpoint_remove (breakpoint, i);
 +    breakpoint->active = !breakpoint->active;
 +    vivi_breakpoint_add (breakpoint, i);
 +  }
 +}
 +
 +/*** AS CODE ***/
 +
 +VIVI_FUNCTION ("breakpoint_active_get", vivi_breakpoint_as_get_active)
 +void
 +vivi_breakpoint_as_get_active (SwfdecAsContext *cx, SwfdecAsObject *this,
 +    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
 +{
 +  if (!VIVI_IS_BREAKPOINT (this))
 +    return;
 +
 +  SWFDEC_AS_VALUE_SET_BOOLEAN (retval, VIVI_BREAKPOINT (this)->active);
 +}
 +
 +VIVI_FUNCTION ("breakpoint_active_set", vivi_breakpoint_as_set_active)
 +void
 +vivi_breakpoint_as_set_active (SwfdecAsContext *cx, SwfdecAsObject *this,
 +    guint argc, SwfdecAsValue *argv, SwfdecAsValue *retval)
 +{
 +  if (!VIVI_IS_BREAKPOINT (this) ||
 +      argc == 0)
 +    return;
 +  vivi_breakpoint_set_active (VIVI_BREAKPOINT (this), swfdec_as_value_to_boolean (cx, &argv[0]));
 +}
 +
diff --cc vivified/core/vivi_wrap.c
index 66eb3a4,0000000..4be1e76
mode 100644,000000..100644
@@@ -1,113 -1,0 +1,113 @@@
 +/* Vivified
 + * 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 "vivi_wrap.h"
 +#include "vivi_application.h"
 +
 +G_DEFINE_TYPE (ViviWrap, vivi_wrap, SWFDEC_TYPE_AS_OBJECT)
 +
 +static void
 +vivi_wrap_dispose (GObject *object)
 +{
 +  ViviWrap *wrap = VIVI_WRAP (object);
 +
 +  if (wrap->wrap) {
 +    g_hash_table_remove (VIVI_APPLICATION (SWFDEC_AS_OBJECT (wrap)->context)->wraps, wrap->wrap);
 +    wrap->wrap = NULL;
 +  }
 +
 +  G_OBJECT_CLASS (vivi_wrap_parent_class)->dispose (object);
 +}
 +
 +static void
 +vivi_wrap_class_init (ViviWrapClass *klass)
 +{
 +  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 +
 +  object_class->dispose = vivi_wrap_dispose;
 +}
 +
 +static void
 +vivi_wrap_init (ViviWrap *wrap)
 +{
 +}
 +
 +SwfdecAsObject *
 +vivi_wrap_object (ViviApplication *app, SwfdecAsObject *object)
 +{
 +  const char *name;
 +  SwfdecAsContext *cx;
 +  SwfdecAsObject *wrap;
 +  SwfdecAsValue val;
 +  
 +  wrap = g_hash_table_lookup (app->wraps, object);
 +  if (wrap)
 +    return wrap;
 +
 +  cx = SWFDEC_AS_CONTEXT (app);
 +  if (!swfdec_as_context_use_mem (cx, sizeof (ViviWrap)))
 +    return NULL;
 +  wrap = g_object_new (VIVI_TYPE_WRAP, NULL);
 +  swfdec_as_object_add (wrap, cx, sizeof (ViviWrap));
 +  /* frames are special */
 +  if (SWFDEC_IS_AS_FRAME (object))
 +    name = "Frame";
 +  else
 +    name = "Wrap";
 +  swfdec_as_object_get_variable (cx->global, swfdec_as_context_get_string (cx, name), &val);
 +  if (SWFDEC_AS_VALUE_IS_OBJECT (&val))
-     swfdec_as_object_set_constructor (wrap, SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE);
++    swfdec_as_object_set_constructor (wrap, SWFDEC_AS_VALUE_GET_OBJECT (&val));
 +  VIVI_WRAP (wrap)->wrap = object;
 +  g_hash_table_insert (app->wraps, object, wrap);
 +  return wrap;
 +}
 +
 +void
 +vivi_wrap_value (ViviApplication *app, SwfdecAsValue *dest, const SwfdecAsValue *src)
 +{
 +  g_return_if_fail (VIVI_IS_APPLICATION (app));
 +  g_return_if_fail (dest != NULL);
 +  g_return_if_fail (SWFDEC_IS_AS_VALUE (src));
 +
 +  switch (src->type) {
 +    case SWFDEC_AS_TYPE_UNDEFINED:
 +    case SWFDEC_AS_TYPE_BOOLEAN:
 +    case SWFDEC_AS_TYPE_NUMBER:
 +    case SWFDEC_AS_TYPE_NULL:
 +      *dest = *src;
 +      break;
 +    case SWFDEC_AS_TYPE_STRING:
 +      SWFDEC_AS_VALUE_SET_STRING (dest,
 +	  swfdec_as_context_get_string (SWFDEC_AS_CONTEXT (app),
 +	    SWFDEC_AS_VALUE_GET_STRING (src)));
 +      break;
 +    case SWFDEC_AS_TYPE_OBJECT:
 +      SWFDEC_AS_VALUE_SET_OBJECT (dest,
 +	  vivi_wrap_object (app, SWFDEC_AS_VALUE_GET_OBJECT (src)));
 +      break;
 +    default:
 +      g_assert_not_reached ();
 +      break;
 +  }
 +}
 +
diff-tree da9fc3e76d3757cb3a8a4459802c753adbbbcbe7 (from 589ed7ba10280a39d4ce2ce5c15863120511b600)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 17:59:23 2007 +0200

    add test checking if flags change for addProperty calls

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 91f6c63..ba9619c 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -46,6 +46,15 @@ EXTRA_DIST = \
 	addProperty-delete-7.swf.trace \
 	addProperty-delete-8.swf \
 	addProperty-delete-8.swf.trace \
+	addProperty-flags.as \
+	addProperty-flags-5.swf \
+	addProperty-flags-5.swf.trace \
+	addProperty-flags-6.swf \
+	addProperty-flags-6.swf.trace \
+	addProperty-flags-7.swf \
+	addProperty-flags-7.swf.trace \
+	addProperty-flags-8.swf \
+	addProperty-flags-8.swf.trace \
 	addProperty-get-prototypes.as \
 	addProperty-get-prototypes-5.swf \
 	addProperty-get-prototypes-5.swf.trace \
diff --git a/test/trace/addProperty-flags-5.swf b/test/trace/addProperty-flags-5.swf
new file mode 100644
index 0000000..c22255d
Binary files /dev/null and b/test/trace/addProperty-flags-5.swf differ
diff --git a/test/trace/addProperty-flags-5.swf.trace b/test/trace/addProperty-flags-5.swf.trace
new file mode 100644
index 0000000..4fc2ce3
--- /dev/null
+++ b/test/trace/addProperty-flags-5.swf.trace
@@ -0,0 +1,6 @@
+Check if flags of variables get reset upon addProperty
+set:
+mark constant:
+overwrite:
+10
+10
diff --git a/test/trace/addProperty-flags-6.swf b/test/trace/addProperty-flags-6.swf
new file mode 100644
index 0000000..74b9adf
Binary files /dev/null and b/test/trace/addProperty-flags-6.swf differ
diff --git a/test/trace/addProperty-flags-6.swf.trace b/test/trace/addProperty-flags-6.swf.trace
new file mode 100644
index 0000000..ea545bd
--- /dev/null
+++ b/test/trace/addProperty-flags-6.swf.trace
@@ -0,0 +1,8 @@
+Check if flags of variables get reset upon addProperty
+set:
+set called
+mark constant:
+overwrite:
+10
+get
+42
diff --git a/test/trace/addProperty-flags-7.swf b/test/trace/addProperty-flags-7.swf
new file mode 100644
index 0000000..237a007
Binary files /dev/null and b/test/trace/addProperty-flags-7.swf differ
diff --git a/test/trace/addProperty-flags-7.swf.trace b/test/trace/addProperty-flags-7.swf.trace
new file mode 100644
index 0000000..ea545bd
--- /dev/null
+++ b/test/trace/addProperty-flags-7.swf.trace
@@ -0,0 +1,8 @@
+Check if flags of variables get reset upon addProperty
+set:
+set called
+mark constant:
+overwrite:
+10
+get
+42
diff --git a/test/trace/addProperty-flags-8.swf b/test/trace/addProperty-flags-8.swf
new file mode 100644
index 0000000..469db26
Binary files /dev/null and b/test/trace/addProperty-flags-8.swf differ
diff --git a/test/trace/addProperty-flags-8.swf.trace b/test/trace/addProperty-flags-8.swf.trace
new file mode 100644
index 0000000..ea545bd
--- /dev/null
+++ b/test/trace/addProperty-flags-8.swf.trace
@@ -0,0 +1,8 @@
+Check if flags of variables get reset upon addProperty
+set:
+set called
+mark constant:
+overwrite:
+10
+get
+42
diff --git a/test/trace/addProperty-flags.as b/test/trace/addProperty-flags.as
new file mode 100644
index 0000000..47049bb
--- /dev/null
+++ b/test/trace/addProperty-flags.as
@@ -0,0 +1,23 @@
+// makeswf -v 7 -s 200x150 -r 1 -o addProperty-flags.swf addProperty-flags.as
+
+trace ("Check if flags of variables get reset upon addProperty");
+
+o = {};
+o.addProperty ("foo", function () { trace ("get"); return 42; }, function () { trace ("set called"); });
+trace ("set:");
+o.foo = 20;
+trace ("mark constant:");
+ASSetPropFlags (o, "foo", 4);
+o.foo = 20;
+trace ("overwrite:");
+o.addProperty ("foo", function () { trace ("get"); return 42; }, function () { trace ("set called"); });
+o.foo = 20;
+
+o.bar = 10;
+ASSetPropFlags (o, "bar", 4);
+trace (o.bar);
+o.addProperty ("bar", function () { trace ("get"); return 42; }, function () { trace ("set called"); });
+
+trace (o.bar);
+
+loadMovie ("FSCommand:quit", "");
diff-tree 589ed7ba10280a39d4ce2ce5c15863120511b600 (from fd36de2f156ce685d5095aaf323e0766ea017bd7)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 17:48:20 2007 +0200

    don't mark addProperty()'d variables as constant when they have no set function

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 213ddb3..83ad4cf 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -1022,8 +1022,6 @@ swfdec_as_object_add_variable (SwfdecAsO
     return;
   var->get = get;
   var->set = set;
-  if (set == NULL)
-    var->flags |= SWFDEC_AS_VARIABLE_CONSTANT;
 }
 
 /*** AS CODE ***/
diff-tree fd36de2f156ce685d5095aaf323e0766ea017bd7 (from c3b035ca1583a420402b965506129bd73ff3f5fe)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 16:02:09 2007 +0200

    no need for that header

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index b303408..cd58cf5 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -38,7 +38,6 @@
 #include "swfdec_initialize.h"
 #include "swfdec_internal.h"
 #include "swfdec_loader_internal.h"
-#include "swfdec_load_object.h"
 #include "swfdec_marshal.h"
 #include "swfdec_movie.h"
 #include "swfdec_script.h"
diff-tree c3b035ca1583a420402b965506129bd73ff3f5fe (from parents)
Merge: 8e61c76bed9526865a3b3a295feaed8e82e2b108 8871593035346615d3b0394184271674d5fd725d
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:47:05 2007 +0200

    Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec/swfdec

diff-tree 8e61c76bed9526865a3b3a295feaed8e82e2b108 (from fc39dd27d21c49d37b3a4fee94b721e798a0fae4)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:45:16 2007 +0200

    gc every time

diff --git a/test/trace/trace.c b/test/trace/trace.c
index 8e5c0f2..af52ef6 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -101,6 +101,7 @@ run_test (gpointer testp, gpointer unuse
   }
   string = g_string_new ("");
   player = swfdec_player_new ();
+  g_object_set (player, "memory-until-gc", (gulong) 0, NULL);
   g_signal_connect (player, "trace", G_CALLBACK (trace_cb), string);
   g_signal_connect (player, "fscommand", G_CALLBACK (fscommand_cb), &quit);
   swfdec_player_set_loader (player, loader);
diff-tree fc39dd27d21c49d37b3a4fee94b721e798a0fae4 (from 076ba52a01ec3e9348822c37781b6cd4b6c24a28)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:45:07 2007 +0200

    GC intervals, too

diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index b1ad1c7..b303408 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1094,6 +1094,7 @@ swfdec_player_mark (SwfdecAsContext *con
   swfdec_as_object_mark (player->MovieClip);
   swfdec_as_object_mark (player->Video);
   g_list_foreach (player->roots, (GFunc) swfdec_as_object_mark, NULL);
+  g_list_foreach (player->intervals, (GFunc) swfdec_as_object_mark, NULL);
   g_list_foreach (player->load_objects, (GFunc) swfdec_as_object_mark, NULL);
 
   SWFDEC_AS_CONTEXT_CLASS (swfdec_player_parent_class)->mark (context);
diff-tree 076ba52a01ec3e9348822c37781b6cd4b6c24a28 (from 613f8fad5514520d82419838475d02e3d704e714)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:44:44 2007 +0200

    reinstate old code that was only commented out for tests
    
    oops

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 23a9396..4e0958b 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -386,8 +386,7 @@ swfdec_as_context_gc (SwfdecAsContext *c
 static gboolean
 swfdec_as_context_needs_gc (SwfdecAsContext *context)
 {
-  return TRUE;
-  //return context->memory_since_gc >= context->memory_until_gc;
+  return context->memory_since_gc >= context->memory_until_gc;
 }
 
 /**
diff-tree 613f8fad5514520d82419838475d02e3d704e714 (from 414a4fc551748f8e3496758e2c2e9207e5ce87a6)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:38:24 2007 +0200

    export property to set how often GC is done

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 75ab9d6..23a9396 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -386,7 +386,8 @@ swfdec_as_context_gc (SwfdecAsContext *c
 static gboolean
 swfdec_as_context_needs_gc (SwfdecAsContext *context)
 {
-  return context->memory_since_gc >= context->memory_until_gc;
+  return TRUE;
+  //return context->memory_since_gc >= context->memory_until_gc;
 }
 
 /**
@@ -417,10 +418,47 @@ enum {
   LAST_SIGNAL
 };
 
+enum {
+  PROP_0,
+  PROP_UNTIL_GC
+};
+
 G_DEFINE_TYPE (SwfdecAsContext, swfdec_as_context, G_TYPE_OBJECT)
 static guint signals[LAST_SIGNAL] = { 0, };
 
 static void
+swfdec_as_context_get_property (GObject *object, guint param_id, GValue *value, 
+    GParamSpec * pspec)
+{
+  SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
+  
+  switch (param_id) {
+    case PROP_UNTIL_GC:
+      g_value_set_ulong (value, (gulong) context->memory_until_gc);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
+swfdec_as_context_set_property (GObject *object, guint param_id, const GValue *value, 
+    GParamSpec * pspec)
+{
+  SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
+  
+  switch (param_id) {
+    case PROP_UNTIL_GC:
+      context->memory_until_gc = g_value_get_ulong (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+  }
+}
+
+static void
 swfdec_as_context_dispose (GObject *object)
 {
   SwfdecAsContext *context = SWFDEC_AS_CONTEXT (object);
@@ -445,6 +483,13 @@ swfdec_as_context_class_init (SwfdecAsCo
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->dispose = swfdec_as_context_dispose;
+  object_class->get_property = swfdec_as_context_get_property;
+  object_class->set_property = swfdec_as_context_set_property;
+
+  g_object_class_install_property (object_class, PROP_UNTIL_GC,
+      g_param_spec_ulong ("memory-until-gc", "memory until gc", 
+	  "amount of bytes that need to be allocated before garbage collection triggers",
+	  0, G_MAXULONG, 8 * 1024 * 1024, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
   /**
    * SwfdecAsContext::trace:
@@ -466,7 +511,6 @@ swfdec_as_context_init (SwfdecAsContext 
 {
   const char *s;
 
-  context->memory_until_gc = 8 * 1024 * 1024; /* 8 MB before we run the GC */
   context->strings = g_hash_table_new (g_str_hash, g_str_equal);
   context->objects = g_hash_table_new (g_direct_hash, g_direct_equal);
 
diff-tree 414a4fc551748f8e3496758e2c2e9207e5ce87a6 (from 5a49ab2a34b19609ae57ac301cb0f3a3af41f140)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:38:08 2007 +0200

    fix memleak

diff --git a/libswfdec/swfdec_flv_decoder.c b/libswfdec/swfdec_flv_decoder.c
index df8054b..43c6b15 100644
--- a/libswfdec/swfdec_flv_decoder.c
+++ b/libswfdec/swfdec_flv_decoder.c
@@ -281,6 +281,7 @@ swfdec_flv_decoder_parse_video_tag (Swfd
     dec->width = cairo_image_surface_get_width (surface);
     dec->height = cairo_image_surface_get_height (surface);
     swfdec_video_decoder_free (decoder);
+    cairo_surface_destroy (surface);
     return SWFDEC_STATUS_INIT;
   } else {
     return SWFDEC_STATUS_IMAGE;
diff-tree 5a49ab2a34b19609ae57ac301cb0f3a3af41f140 (from adede979b9a128b32eb3c911e1ffa51858a8b312)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:26:32 2007 +0200

    fix memleak

diff --git a/test/trace/trace.c b/test/trace/trace.c
index 9725a0b..8e5c0f2 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -182,6 +182,8 @@ run_test (gpointer testp, gpointer unuse
   g_string_append (output, "  OK\n");
   test->success = TRUE;
 fail:
+  if (inter)
+    swfdec_interaction_free (inter);
   if (test->mutex)
     g_mutex_lock (test->mutex);
   test->output = g_string_free (output, FALSE);
diff-tree adede979b9a128b32eb3c911e1ffa51858a8b312 (from 04882c75cb8e4b84312af73281c8df32b808ca88)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 15:10:25 2007 +0200

    fix garbage collection
    
    Also plug a memleak by not freeing the load object list on dispose

diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
index 4d00a61..a8a51a7 100644
--- a/libswfdec/swfdec_load_object.c
+++ b/libswfdec/swfdec_load_object.c
@@ -148,6 +148,14 @@ swfdec_load_object_reset (SwfdecLoadObje
 }
 
 static void
+swfdec_load_object_mark (SwfdecAsObject *object)
+{
+  swfdec_as_object_mark (SWFDEC_LOAD_OBJECT (object)->target);
+
+  SWFDEC_AS_OBJECT_CLASS (swfdec_load_object_parent_class)->mark (object);
+}
+
+static void
 swfdec_load_object_dispose (GObject *object)
 {
   SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (object);
@@ -161,8 +169,11 @@ static void
 swfdec_load_object_class_init (SwfdecLoadObjectClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  SwfdecAsObjectClass *as_object_class = SWFDEC_AS_OBJECT_CLASS (klass);
 
   object_class->dispose = swfdec_load_object_dispose;
+
+  as_object_class->mark = swfdec_load_object_mark;
 }
 
 static void
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 942dadf..b1ad1c7 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -666,6 +666,7 @@ swfdec_player_dispose (GObject *object)
   }
   g_assert (player->timeouts == NULL);
   g_list_free (player->intervals);
+  g_list_free (player->load_objects);
   player->intervals = NULL;
   g_assert (g_queue_is_empty (player->init_queue));
   g_assert (g_queue_is_empty (player->construct_queue));
@@ -1088,18 +1089,12 @@ static void
 swfdec_player_mark (SwfdecAsContext *context)
 {
   SwfdecPlayer *player = SWFDEC_PLAYER (context);
-  GList *walk;
 
   g_hash_table_foreach (player->registered_classes, swfdec_player_mark_string_object, NULL);
   swfdec_as_object_mark (player->MovieClip);
   swfdec_as_object_mark (player->Video);
-  for (walk = player->roots; walk; walk = walk->next) {
-    swfdec_as_object_mark (walk->data);
-  }
-  for (walk = player->load_objects; walk; walk = walk->next) {
-    swfdec_as_object_mark (walk->data);
-    swfdec_as_object_mark (SWFDEC_LOAD_OBJECT (walk->data)->target);
-  }
+  g_list_foreach (player->roots, (GFunc) swfdec_as_object_mark, NULL);
+  g_list_foreach (player->load_objects, (GFunc) swfdec_as_object_mark, NULL);
 
   SWFDEC_AS_CONTEXT_CLASS (swfdec_player_parent_class)->mark (context);
 }
diff-tree 04882c75cb8e4b84312af73281c8df32b808ca88 (from c13484c2bf562b37799aa5cce70beb04fe430cd6)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 13:43:50 2007 +0200

    fix valgrind reported memleaks

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 23e4116..4a712c2 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -331,7 +331,7 @@ swfdec_action_push (SwfdecAsContext *cx,
 	  if (s == NULL)
 	    return;
 	  SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_push (cx), 
-	      swfdec_as_context_get_string (cx, s));
+	      swfdec_as_context_give_string (cx, s));
 	  break;
 	}
       case 1: /* float */
diff-tree c13484c2bf562b37799aa5cce70beb04fe430cd6 (from fc811de19b9f90a01513466483a782c28fa8bbe1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 13:43:19 2007 +0200

    fix valgrind reported memleaks

diff --git a/libswfdec/swfdec_codec_screen.c b/libswfdec/swfdec_codec_screen.c
index b0d757e..2cb6312 100644
--- a/libswfdec/swfdec_codec_screen.c
+++ b/libswfdec/swfdec_codec_screen.c
@@ -106,6 +106,7 @@ swfdec_video_decoder_screen_decode (Swfd
 	  out[x * 4 - y * stride + SWFDEC_COLOR_INDEX_ALPHA] = 0xFF;
 	}
       }
+      swfdec_buffer_unref (buf);
     }
   }
   *width = screen->width;
diff-tree 8871593035346615d3b0394184271674d5fd725d (from fdee654c4bc721aa1c18167bcaa7b52183565c96)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 14:39:30 2007 +0300

    Improve propflags test case
    
    Split most of the code to trace_properties.as so it can be included from other
    test too

diff --git a/test/trace/propflags-5.swf b/test/trace/propflags-5.swf
index 644c5ac..893b801 100644
Binary files a/test/trace/propflags-5.swf and b/test/trace/propflags-5.swf differ
diff --git a/test/trace/propflags-5.swf.trace b/test/trace/propflags-5.swf.trace
index eeaa55a..e7da22a 100644
--- a/test/trace/propflags-5.swf.trace
+++ b/test/trace/propflags-5.swf.trace
@@ -1,3 +1,11 @@
-Hidden: 1,3,5,7,__constructor__,__proto__,constructor
-Constant: 4,5,6,7
-Permanent: 
+   
+h  
+   
+h  
+  c
+h c
+  c
+h c
+h  
+h  
+h  
diff --git a/test/trace/propflags-6.swf b/test/trace/propflags-6.swf
index 2af13d8..c702cf4 100644
Binary files a/test/trace/propflags-6.swf and b/test/trace/propflags-6.swf differ
diff --git a/test/trace/propflags-6.swf.trace b/test/trace/propflags-6.swf.trace
index 8d59d4e..a3858d3 100644
--- a/test/trace/propflags-6.swf.trace
+++ b/test/trace/propflags-6.swf.trace
@@ -1,3 +1,11 @@
-Hidden: 1,3,5,7,__constructor__,__proto__,constructor
-Constant: 4,5,6,7
-Permanent: 2,3,6,7,__proto__
+    0 = 0
+h   1 = 1
+ p  2 = 2
+hp  3 = 3
+  c 4 = 4
+h c 5 = 5
+ pc 6 = 6
+hpc 7 = 7
+h   __constructor__ = [type Function]
+hp  __proto__ = [object Object]
+h   constructor = [type Function] __proto__.constructor = [type Function]
diff --git a/test/trace/propflags-7.swf b/test/trace/propflags-7.swf
index 9ae55c5..8780cfb 100644
Binary files a/test/trace/propflags-7.swf and b/test/trace/propflags-7.swf differ
diff --git a/test/trace/propflags-7.swf.trace b/test/trace/propflags-7.swf.trace
index 74b639d..3c66620 100644
--- a/test/trace/propflags-7.swf.trace
+++ b/test/trace/propflags-7.swf.trace
@@ -1,3 +1,10 @@
-Hidden: 1,3,5,7,__constructor__,__proto__
-Constant: 4,5,6,7
-Permanent: 2,3,6,7,__proto__
+    0 = 0
+h   1 = 1
+ p  2 = 2
+hp  3 = 3
+  c 4 = 4
+h c 5 = 5
+ pc 6 = 6
+hpc 7 = 7
+h   __constructor__ = [type Function]
+hp  __proto__ = [object Object]
diff --git a/test/trace/propflags.as b/test/trace/propflags.as
index 34ce251..daca383 100644
--- a/test/trace/propflags.as
+++ b/test/trace/propflags.as
@@ -1,83 +1,14 @@
-// makeswf -v 7 -r 1 -o test-7.swf test.as
+// makeswf -v 7 -r 1 -o propflags-7.swf propflags.as
 
-function hidden_properties (obj)
-{
-  normal = new Array ();
-  for (prop in obj) {
-    normal.push (prop);
-  }
+#include "trace_properties.as"
 
-  hidden = new Array ();
-  ASSetPropFlags (obj, null, 0, 1);
-  for (prop in obj) {
-    for (i = 0; i < normal.length; i++) {
-      if (normal[i] == prop)
-	break;
-    }
-    if (i == normal.length)
-      hidden.push (prop);
-  }
-  ASSetPropFlags (obj, hidden, 1, 0);
-
-  return hidden.sort ();
-}
-
-// loses flags from the properties that are not permanent
-function permanent_properties (obj)
-{
-  hidden = hidden_properties (obj);
-  constant = constant_properties (obj);
-
-  ASSetPropFlags (obj, hidden, 0, 1);
-
-  permanent = new Array();
-  for (var prop in obj) {
-    var old = obj[prop];
-    delete obj[prop];
-    if (obj.hasOwnProperty (prop)) {
-      permanent.push (prop);
-    } else {
-      obj[prop] = old;
-    }
-  }
-
-  ASSetPropFlags (obj, hidden, 1, 0);
-  ASSetPropFlags (obj, constant, 3, 0);
-
-  return permanent.sort ();
-}
-
-function constant_properties (obj)
-{
-  hidden = hidden_properties (obj);
-
-  ASSetPropFlags (obj, hidden, 0, 1);
-
-  constant = new Array();
-  for (var prop in obj) {
-    var old = obj[prop];
-    var val = "hello " + obj[prop];
-    obj[prop] = val;
-    if (obj[prop] != val) {
-      constant.push (prop);
-    } else {
-      obj[prop] = old;
-    }
-  }
-
-  ASSetPropFlags (obj, hidden, 1, 0);
-
-  return constant.sort ();
-}
-
-var obj = new Object ();
-obj[0] = 0;
+var o = new Object ();
+o[0] = 0;
 for (var i = 1; i <= 7; i++) {
-  obj[i] = i;
-  ASSetPropFlags (obj, i, i, 0);
+  o[i] = i;
+  ASSetPropFlags (o, i, i, 0);
 }
-trace ("Hidden: " + hidden_properties (obj));
-trace ("Constant: " + constant_properties (obj));
-trace ("Permanent: " + permanent_properties (obj));
+
+trace_properties (o);
 
 loadMovie ("FSCommand:quit", "");
diff --git a/test/trace/trace_properties.as b/test/trace/trace_properties.as
new file mode 100644
index 0000000..a62fea1
--- /dev/null
+++ b/test/trace/trace_properties.as
@@ -0,0 +1,147 @@
+// doesn't work right in Flash 5
+
+function new_empty_object () {
+  var hash = new Object ();
+  ASSetPropFlags (hash, null, 0, 7);
+  for (var prop in hash) {
+    delete hash[prop];
+  }
+  return hash;
+}
+
+function new_info () {
+  return new_empty_object ();
+}
+
+function set_info (info, prop, id, value) {
+  info[prop + "_-_" + id] = value;
+}
+
+function get_info (info, prop, id) {
+  return info[prop + "_-_" + id];
+}
+
+// print all properties of a given object, flags are:
+// h = hidden
+// p = permanent
+// P = permanent even without propflag
+// c = constant
+// C = constant even without propflag
+function trace_properties (o)
+{
+  var info = new_info ();
+  for (var prop in o) {
+    set_info (info, prop, "hidden", false);
+  }
+
+  var hidden = new Array ();
+
+  ASSetPropFlags (o, null, 0, 1);
+
+  var all = new Array ();
+  for (var prop in o) {
+    all.push (prop);
+    if (o.hasOwnProperty (prop)) {
+      set_info (info, prop, "outproto", true);
+    } else {
+      set_info (info, prop, "outproto", false);
+    }
+    if (o.__proto__.hasOwnProperty (prop)) {
+      set_info (info, prop, "inproto", true);
+    } else {
+      set_info (info, prop, "inproto", false);
+    }
+  }
+  all.sort ();
+
+  for (var prop in o) {
+    if (get_info (info, prop, "hidden") != false) {
+      set_info (info, prop, "hidden", true);
+      hidden.push (prop);
+    }
+  }
+
+  for (var prop in o) {
+    var old = o[prop];
+    var val = "hello " + o[prop];
+    o[prop] = val;
+    if (o[prop] != val) {
+      set_info (info, prop, "constant", true);
+      ASSetPropFlags (o, prop, 0, 4);
+      o[prop] = val;
+      if (o[prop] != val) {
+	set_info (info, prop, "superconstant", true);
+      } else {
+	set_info (info, prop, "superconstant", false);
+	o[prop] = old;
+      }
+      ASSetPropFlags (o, prop, 4);
+    } else {
+      set_info (info, prop, "constant", false);
+      set_info (info, prop, "superconstant", false);
+      o[prop] = old;
+    }
+  }
+
+  for (var prop in o) {
+    ASSetPropFlags (o, prop, 0, 4);
+    var old = o[prop];
+    delete o[prop];
+    if (o.hasOwnProperty (prop)) {
+      set_info (info, prop, "permanent", true);
+      ASSetPropFlags (o, prop, 0, 2);
+      delete o[prop];
+      if (o.hasOwnProperty (prop)) {
+	set_info (info, prop, "superpermanent", true);
+      } else {
+	set_info (info, prop, "superpermanent", false);
+	o[prop] = old;
+      }
+      ASSetPropFlags (o, prop, 4);
+    } else {
+      set_info (info, prop, "permanent", false);
+      o[prop] = old;
+    }
+    if (get_info (info, prop, "constant") == true)
+      ASSetPropFlags (o, prop, 4);
+  }
+
+  ASSetPropFlags (o, hidden, 1, 0);
+
+  for (var i = 0; i < all.length; i++) {
+    var flags = "";
+
+    if (get_info (info, all[i], "hidden") == true) {
+      flags += "h";
+    } else {
+      flags += " ";
+    }
+
+    if (get_info (info, all[i], "superpermanent") == true) {
+      flags += "P";
+    } else if (get_info (info, all[i], "permanent") == true) {
+      flags += "p";
+    } else {
+      flags += " ";
+    }
+
+    if (get_info (info, all[i], "superconstant") == true) {
+      flags += "C";
+    } else if (get_info (info, all[i], "constant") == true) {
+      flags += "c";
+    } else {
+      flags += " ";
+    }
+
+    values = "";
+
+    if (get_info (info, all[i], "outproto") == true) {
+      values += " " + all[i] + " = " + o[all[i]];
+    }
+    if (get_info (info, all[i], "inproto") == true) {
+      values += " __proto__." + all[i] + " = " + o.__proto__[all[i]];
+    }
+
+    trace (flags + values);
+  }
+}
diff-tree fdee654c4bc721aa1c18167bcaa7b52183565c96 (from daed3a3bd2d1517f271c8868670148eba0af3c8f)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 14:17:53 2007 +0300

    Fix errors in ASSetPropFlags

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 75ab9d6..9e71c0d 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -1018,7 +1018,7 @@ swfdec_as_context_ASSetPropFlags_foreach
   guint *flags = data;
 
   /* shortcut if the flags already match */
-  if ((cur_flags & flags[1]) == flags[0])
+  if (cur_flags == ((cur_flags &~ flags[1]) | flags[0]))
     return TRUE;
 
   swfdec_as_context_ASSetPropFlags_set_one_flag (object, s, flags);
@@ -1039,7 +1039,7 @@ swfdec_as_context_ASSetPropFlags (Swfdec
     return;
   obj = SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]);
   flags[0] = swfdec_as_value_to_integer (cx, &argv[2]);
-  flags[1] = (argc > 3) ? swfdec_as_value_to_integer (cx, &argv[3]) : -1;
+  flags[1] = (argc > 3) ? swfdec_as_value_to_integer (cx, &argv[3]) : 0;
   if (SWFDEC_AS_VALUE_IS_NULL (&argv[1])) {
     swfdec_as_object_foreach (obj, swfdec_as_context_ASSetPropFlags_foreach, flags);
   } else {
diff-tree fc811de19b9f90a01513466483a782c28fa8bbe1 (from 614cf854109af1972529510d686fa67945f06ff0)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 13:06:46 2007 +0200

    fix valgrind reported memleaks

diff --git a/libswfdec/swfdec_player_as.c b/libswfdec/swfdec_player_as.c
index 125b9e8..1b8503a 100644
--- a/libswfdec/swfdec_player_as.c
+++ b/libswfdec/swfdec_player_as.c
@@ -161,13 +161,13 @@ ASSetNative (SwfdecAsContext *cx, Swfdec
     function = swfdec_get_asnative (cx, x, y);
     if (function == NULL) {
       SWFDEC_FIXME ("no ASnative function for %u, %u, what now?", x, y);
-      return;
+      break;
     }
     SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (function));
     swfdec_as_object_set_variable (target, swfdec_as_context_get_string (cx, s), &val);
     y++;
   }
-  g_free (names);
+  g_strfreev (names);
 }
 
 SWFDEC_AS_NATIVE (4, 1, ASSetNativeAccessor)
@@ -202,12 +202,12 @@ ASSetNativeAccessor (SwfdecAsContext *cx
     set = swfdec_get_asnative (cx, x, y++);
     if (get == NULL) {
       SWFDEC_ERROR ("no getter for %s", s);
-      return;
+      break;
     }
     swfdec_as_object_add_variable (target, swfdec_as_context_get_string (cx, s),
 	get, set);
   }
-  g_free (names);
+  g_strfreev (names);
 }
 
 static void
diff-tree 614cf854109af1972529510d686fa67945f06ff0 (from a4b5d04765d9c1f62c525a0d14097c3cc65aed23)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 13:06:39 2007 +0200

    fix valgrind reported memleaks

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 9e69d46..23e4116 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1465,7 +1465,7 @@ static void
 swfdec_action_define_function (SwfdecAsContext *cx, guint action,
     const guint8 *data, guint len)
 {
-  const char *function_name;
+  char *function_name;
   const char *name = NULL;
   guint i, n_args, size, n_registers;
   SwfdecBuffer *buffer;
@@ -1533,6 +1533,7 @@ swfdec_action_define_function (SwfdecAsC
   if (frame->script->buffer->data + frame->script->buffer->length < frame->pc + 3 + len + size) {
     SWFDEC_ERROR ("size of function is too big");
     g_free (args);
+    g_free (function_name);
     return;
   }
   /* create the script */
@@ -1554,9 +1555,11 @@ swfdec_action_define_function (SwfdecAsC
   if (name == NULL)
     name = "unnamed_function";
   script = swfdec_script_new (&bits, name, cx->version);
+  swfdec_buffer_unref (buffer);
   if (script == NULL) {
     SWFDEC_ERROR ("failed to create script");
     g_free (args);
+    g_free (function_name);
     return;
   }
   if (frame->constant_pool_buffer)
@@ -1574,13 +1577,14 @@ swfdec_action_define_function (SwfdecAsC
   } else {
     SwfdecAsValue funval;
     /* FIXME: really varobj? Not eval or sth like that? */
-    function_name = swfdec_as_context_get_string (cx, function_name);
+    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_set_variable (frame->target, name, &funval);
   }
 
   /* update current context */
   frame->pc += 3 + len + size;
+  g_free (function_name);
 }
 
 static void
diff-tree a4b5d04765d9c1f62c525a0d14097c3cc65aed23 (from parents)
Merge: d2af9b321edb904a42f483ff806ac6dfbdce9b59 58a57fd8b8361870a39382099717b3fe2fdf38e7
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 12:35:01 2007 +0200

    Merge branch 'master' of ssh://company@git.freedesktop.org/git/swfdec/swfdec

diff-tree d2af9b321edb904a42f483ff806ac6dfbdce9b59 (from 409340bd1cd81d54715abb7d816f9f2e076432e9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 12:34:43 2007 +0200

    rework delete so it can return TRUE, FALSE, AND MAYBE

diff --git a/libswfdec/swfdec_as_frame.c b/libswfdec/swfdec_as_frame.c
index 4608b0a..d47f589 100644
--- a/libswfdec/swfdec_as_frame.c
+++ b/libswfdec/swfdec_as_frame.c
@@ -503,20 +503,21 @@ swfdec_as_frame_find_variable (SwfdecAsF
   return NULL;
 }
 
-/* FIXME: merge with find_variable somehow */
-gboolean
+SwfdecAsDeleteReturn
 swfdec_as_frame_delete_variable (SwfdecAsFrame *frame, const char *variable)
 {
   SwfdecAsScope *cur;
   guint i;
+  SwfdecAsDeleteReturn ret;
 
   g_return_val_if_fail (SWFDEC_IS_AS_FRAME (frame), FALSE);
   g_return_val_if_fail (variable != NULL, FALSE);
 
   cur = frame->scope;
   for (i = 0; i < 256; i++) {
-    if (swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (cur), variable))
-      return TRUE;
+    ret = swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (cur), variable);
+    if (ret)
+      return ret;
     if (cur->next == NULL)
       break;
     cur = cur->next;
@@ -528,8 +529,9 @@ swfdec_as_frame_delete_variable (SwfdecA
   g_assert (SWFDEC_IS_AS_FRAME (cur));
   /* we've walked the scope chain down. Now look in the special objects. */
   /* 1) the target set via SetTarget */
-  if (swfdec_as_object_delete_variable (frame->target, variable))
-    return TRUE;
+  ret = swfdec_as_object_delete_variable (frame->target, variable);
+  if (ret)
+    return ret;
   /* 2) the global object */
   return swfdec_as_object_delete_variable (SWFDEC_AS_OBJECT (frame)->context->global, variable);
 }
diff --git a/libswfdec/swfdec_as_frame_internal.h b/libswfdec/swfdec_as_frame_internal.h
index f6d7644..ca435c9 100644
--- a/libswfdec/swfdec_as_frame_internal.h
+++ b/libswfdec/swfdec_as_frame_internal.h
@@ -70,7 +70,8 @@ void		swfdec_as_frame_preload		(SwfdecAs
 
 SwfdecAsObject *swfdec_as_frame_find_variable	(SwfdecAsFrame *	frame,
 						 const char *		variable);
-gboolean	swfdec_as_frame_delete_variable	(SwfdecAsFrame *	frame,
+SwfdecAsDeleteReturn
+		swfdec_as_frame_delete_variable	(SwfdecAsFrame *	frame,
 						 const char *		variable);
 
 void		swfdec_as_frame_set_target	(SwfdecAsFrame *	frame,
diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 72cf447..9e69d46 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1713,8 +1713,10 @@ swfdec_action_delete (SwfdecAsContext *c
   
   name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));
   val = swfdec_as_stack_peek (cx, 2);
-  if (SWFDEC_AS_VALUE_IS_OBJECT (val))
-    success = swfdec_as_object_delete_variable (SWFDEC_AS_VALUE_GET_OBJECT (val), name);
+  if (SWFDEC_AS_VALUE_IS_OBJECT (val)) {
+    success = swfdec_as_object_delete_variable (
+	SWFDEC_AS_VALUE_GET_OBJECT (val), name) == SWFDEC_AS_DELETE_DELETED;
+  }
   SWFDEC_AS_VALUE_SET_BOOLEAN (val, success);
   swfdec_as_stack_pop_n (cx, 1);
 }
@@ -1724,10 +1726,12 @@ swfdec_action_delete2 (SwfdecAsContext *
 {
   SwfdecAsValue *val;
   const char *name;
+  gboolean success = FALSE;
   
   val = swfdec_as_stack_peek (cx, 1);
   name = swfdec_as_value_to_string (cx, val);
-  SWFDEC_AS_VALUE_SET_BOOLEAN (val, swfdec_as_frame_delete_variable (cx->frame, name));
+  success = swfdec_as_frame_delete_variable (cx->frame, name) == SWFDEC_AS_DELETE_DELETED;
+  SWFDEC_AS_VALUE_SET_BOOLEAN (val, success);
 }
 
 static void
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 749b0d7..213ddb3 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -73,6 +73,18 @@
  */
 
 /**
+ * SwfdecAsDeleteReturn:
+ * @SWFDEC_AS_DELETE_NOT_FOUND: The variable was not found and therefore 
+ *                              couldn't be deleted.
+ * @SWFDEC_AS_DELETE_DELETED: The variable was deleted.
+ * @SWFDEC_AS_DELETE_NOT_DELETED: The variable was found but could not be 
+ *                                deleted.
+ *
+ * This is the return value used by swfdec_as_object_delete_variable(). It 
+ * describes the various outcomes of trying to delete a variable.
+ */
+
+/**
  * SwfdecAsVariableForeach:
  * @object: The object this function is run on
  * @variable: garbage-collected name of the current variables
@@ -266,22 +278,22 @@ swfdec_as_object_free_property (gpointer
   g_slice_free (SwfdecAsVariable, value);
 }
 
-static gboolean
+static SwfdecAsDeleteReturn
 swfdec_as_object_do_delete (SwfdecAsObject *object, const char *variable)
 {
   SwfdecAsVariable *var;
 
   var = g_hash_table_lookup (object->properties, variable);
   if (var == NULL)
-    return FALSE;
+    return SWFDEC_AS_DELETE_NOT_FOUND;
   if (var->flags & SWFDEC_AS_VARIABLE_PERMANENT)
-    return TRUE;
+    return SWFDEC_AS_DELETE_NOT_DELETED;
 
   swfdec_as_object_free_property (NULL, var, object);
   if (!g_hash_table_remove (object->properties, variable)) {
     g_assert_not_reached ();
   }
-  return TRUE;
+  return SWFDEC_AS_DELETE_DELETED;
 }
 
 typedef struct {
@@ -647,11 +659,9 @@ swfdec_as_object_get_variable_and_flags 
  * Deletes the given variable if possible. If the variable is protected from 
  * deletion, it will not be deleted.
  *
- * Returns: %TRUE if the variable existed. Note that this doesn't mean that the
- *          variable was actually removed. Permanent variables for example 
- *          cannot be removed.
+ * Returns: See #SwfdecAsDeleteReutnr for details of the return value.
  **/
-gboolean
+SwfdecAsDeleteReturn
 swfdec_as_object_delete_variable (SwfdecAsObject *object, const char *variable)
 {
   SwfdecAsObjectClass *klass;
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 1109110..e396294 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -34,6 +34,12 @@ typedef enum {
   SWFDEC_AS_VARIABLE_FLASH6_UP = (1 << 7)
 } SwfdecAsVariableFlag;
 
+typedef enum {
+  SWFDEC_AS_DELETE_NOT_FOUND = 0,
+  SWFDEC_AS_DELETE_DELETED,
+  SWFDEC_AS_DELETE_NOT_DELETED
+} SwfdecAsDeleteReturn;
+
 typedef struct _SwfdecAsObjectClass SwfdecAsObjectClass;
 typedef gboolean (* SwfdecAsVariableForeach) (SwfdecAsObject *object, 
     const char *variable, SwfdecAsValue *value, guint flags, gpointer data);
@@ -80,7 +86,7 @@ struct _SwfdecAsObjectClass {
 						 guint			flags,
 						 guint			mask);
   /* delete the variable - return TRUE if it exists */
-  gboolean		(* del)			(SwfdecAsObject *       object,
+  SwfdecAsDeleteReturn	(* del)			(SwfdecAsObject *       object,
 						 const char *		variable);
   /* call with every variable until func returns FALSE */
   gboolean		(* foreach)		(SwfdecAsObject *	object,
@@ -129,7 +135,8 @@ gboolean	swfdec_as_object_get_variable_a
 						 SwfdecAsValue *	value,
 						 guint *		flags,
 						 SwfdecAsObject **	pobject);
-gboolean	swfdec_as_object_delete_variable(SwfdecAsObject *	object,
+SwfdecAsDeleteReturn
+		swfdec_as_object_delete_variable(SwfdecAsObject *	object,
 						 const char *		variable);
 void		swfdec_as_object_set_variable_flags
 						(SwfdecAsObject *       object,
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index aa75a0b..c66d93b 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -99,11 +99,11 @@ swfdec_as_super_set_flags (SwfdecAsObjec
   /* if we have no variables, we also can't set its flags... */
 }
 
-static gboolean
+static SwfdecAsDeleteReturn
 swfdec_as_super_delete (SwfdecAsObject *object, const char *variable)
 {
   /* if we have no variables... */
-  return FALSE;
+  return SWFDEC_AS_DELETE_NOT_FOUND;
 }
 
 static SwfdecAsObject *
diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c
index a6b032e..4484079 100644
--- a/libswfdec/swfdec_as_with.c
+++ b/libswfdec/swfdec_as_with.c
@@ -78,7 +78,7 @@ swfdec_as_with_set_flags (SwfdecAsObject
   klass->set_flags (with->object, variable, flags, mask);
 }
 
-static gboolean
+static SwfdecAsDeleteReturn
 swfdec_as_with_delete (SwfdecAsObject *object, const char *variable)
 {
   SwfdecAsWith *with = SWFDEC_AS_WITH (object);
diff-tree daed3a3bd2d1517f271c8868670148eba0af3c8f (from 58a57fd8b8361870a39382099717b3fe2fdf38e7)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 13:34:18 2007 +0300

    Forgot to add .txt file for loadvars test

diff --git a/test/trace/loadvars-5.swf b/test/trace/loadvars-5.swf
index 1c89902..42c7476 100644
Binary files a/test/trace/loadvars-5.swf and b/test/trace/loadvars-5.swf differ
diff --git a/test/trace/loadvars-6.swf b/test/trace/loadvars-6.swf
index 5d623a9..56ae085 100644
Binary files a/test/trace/loadvars-6.swf and b/test/trace/loadvars-6.swf differ
diff --git a/test/trace/loadvars-6.swf.trace b/test/trace/loadvars-6.swf.trace
index 093c6d0..3a22913 100644
--- a/test/trace/loadvars-6.swf.trace
+++ b/test/trace/loadvars-6.swf.trace
@@ -1,39 +1,51 @@
 [type Function]
 undefined
-onData: test=2&moi=terve&tyhja&=taysi&hehe=jotain%20muuta&hehe2=jotain muuta&on=lal=lel=luu
+onData: test=2&hi=hello&empty_value&=empty_name&spa%20ce=spa%20ce&sp ace&spa ce=sp ace&many=equal=signs=in=row&eof=
+was there&eof
+=was there&
 
 false
-84
-84
+134
+134
 onLoad: true
 true
-84
-84
-hehe = jotain muuta
-hehe2 = jotain muuta
-moi = terve
-on = lal=lel=luu
+134
+134
 
+ = 
+empty_value = 
+eof = 
+was there
+eof
+ = was there
+hi = hello
+many = equal=signs=in=row
 onData = [type Function]
 onDataReal = [type Function]
 onLoad = [type Function]
+sp ace = 
+spa ce = sp ace
 test = 2
-tyhja = 
 onData: 
 true
-84
-84
+134
+134
 onLoad: false
 true
-84
-84
-hehe = jotain muuta
-hehe2 = jotain muuta
-moi = terve
-on = lal=lel=luu
+134
+134
 
+ = 
+empty_value = 
+eof = 
+was there
+eof
+ = was there
+hi = hello
+many = equal=signs=in=row
 onData = [type Function]
 onDataReal = [type Function]
 onLoad = [type Function]
+sp ace = 
+spa ce = sp ace
 test = 2
-tyhja = 
diff --git a/test/trace/loadvars-7.swf b/test/trace/loadvars-7.swf
index 7af6ca7..ee18028 100644
Binary files a/test/trace/loadvars-7.swf and b/test/trace/loadvars-7.swf differ
diff --git a/test/trace/loadvars-7.swf.trace b/test/trace/loadvars-7.swf.trace
index 11f965b..95d654a 100644
--- a/test/trace/loadvars-7.swf.trace
+++ b/test/trace/loadvars-7.swf.trace
@@ -1,39 +1,51 @@
 [type Function]
 undefined
-onData: test=2&moi=terve&tyhja&=taysi&hehe=jotain%20muuta&hehe2=jotain muuta&on=lal=lel=luu
+onData: test=2&hi=hello&empty_value&=empty_name&spa%20ce=spa%20ce&sp ace&spa ce=sp ace&many=equal=signs=in=row&eof=
+was there&eof
+=was there&
 
 false
-84
-84
+134
+134
 onLoad: true
 true
-84
-84
-hehe = jotain muuta
-hehe2 = jotain muuta
-moi = terve
-on = lal=lel=luu
+134
+134
 
+ = 
+empty_value = 
+eof = 
+was there
+eof
+ = was there
+hi = hello
+many = equal=signs=in=row
 onData = [type Function]
 onDataReal = [type Function]
 onLoad = [type Function]
+sp ace = 
+spa ce = sp ace
 test = 2
-tyhja = 
 onData: undefined
 true
-84
-84
+134
+134
 onLoad: false
 true
-84
-84
-hehe = jotain muuta
-hehe2 = jotain muuta
-moi = terve
-on = lal=lel=luu
+134
+134
 
+ = 
+empty_value = 
+eof = 
+was there
+eof
+ = was there
+hi = hello
+many = equal=signs=in=row
 onData = [type Function]
 onDataReal = [type Function]
 onLoad = [type Function]
+sp ace = 
+spa ce = sp ace
 test = 2
-tyhja = 
diff --git a/test/trace/loadvars.as b/test/trace/loadvars.as
index b21ea99..b3203a4 100644
--- a/test/trace/loadvars.as
+++ b/test/trace/loadvars.as
@@ -29,8 +29,8 @@ lv.onLoad = function (success) {
   }
 };
 
-lv.load ("params.txt");
-lv.load ("blah.txt");
+lv.load ("loadvars.txt");
+lv.load ("404");
 
 function quit () {
   loadMovie ("FSCommand:quit", "");
diff --git a/test/trace/loadvars.txt b/test/trace/loadvars.txt
new file mode 100644
index 0000000..867ba7e
--- /dev/null
+++ b/test/trace/loadvars.txt
@@ -0,0 +1,3 @@
+test=2&hi=hello&empty_value&=empty_name&spa%20ce=spa%20ce&sp ace&spa ce=sp ace&many=equal=signs=in=row&eof=
+was there&eof
+=was there&
diff-tree 58a57fd8b8361870a39382099717b3fe2fdf38e7 (from 89b02c75b20577ae409d62deef48e1d9942ffdcd)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 12:39:59 2007 +0300

    Make LoadVars's properties use the propflag to disable them in v5

diff --git a/libswfdec/swfdec_initialize.as b/libswfdec/swfdec_initialize.as
index dde8fce..009bbcc 100644
--- a/libswfdec/swfdec_initialize.as
+++ b/libswfdec/swfdec_initialize.as
@@ -120,4 +120,4 @@ LoadVars.prototype.getBytesTotal = funct
   return this._bytesTotal;
 };
 
-ASSetPropFlags(LoadVars.prototype, null, 1);
+ASSetPropFlags(LoadVars.prototype, null, 129);
diff --git a/libswfdec/swfdec_initialize.h b/libswfdec/swfdec_initialize.h
index c991bc5..15a9916 100644
--- a/libswfdec/swfdec_initialize.h
+++ b/libswfdec/swfdec_initialize.h
@@ -130,7 +130,7 @@ const unsigned char swfdec_initialize[] 
   0x0D, 0x00, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x3F, 0x4E, 0x3E, 0x4F,
   0x96, 0x02, 0x00, 0x08,  0x2F, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x30, 0x4E,  0x96, 0x02, 0x00, 0x08,
   0x40, 0x9B, 0x05, 0x00,  0x00, 0x00, 0x00, 0x0D,  0x00, 0x96, 0x02, 0x00,  0x08, 0x06, 0x1C, 0x96,
-  0x02, 0x00, 0x08, 0x41,  0x4E, 0x3E, 0x4F, 0x96,  0x08, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x02,
+  0x02, 0x00, 0x08, 0x41,  0x4E, 0x3E, 0x4F, 0x96,  0x08, 0x00, 0x07, 0x81,  0x00, 0x00, 0x00, 0x02,
   0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x07, 0x00,  0x07, 0x03, 0x00, 0x00,
   0x00, 0x08, 0x13, 0x3D,  0x17, 0x00
 };
diff-tree 89b02c75b20577ae409d62deef48e1d9942ffdcd (from b73fa2d44918c74e7ea8797f9f54a61b63b80245)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 12:24:50 2007 +0300

    Fixes to LoadVars implementation

diff --git a/libswfdec/swfdec_initialize.as b/libswfdec/swfdec_initialize.as
index bd6215d..dde8fce 100644
--- a/libswfdec/swfdec_initialize.as
+++ b/libswfdec/swfdec_initialize.as
@@ -80,9 +80,6 @@ ASSetNativeAccessor (Stage, 666, "scaleM
 
 function LoadVars () { };
 
-LoadVars.prototype.loaded = undefined;
-LoadVars.prototype._bytesLoaded = undefined;
-LoadVars.prototype._bytesTotal = undefined;
 LoadVars.prototype.contentType = "application/x-www-form-urlencoded";
 
 LoadVars.prototype.load = ASnative (301, 0);
@@ -94,9 +91,9 @@ LoadVars.prototype.onLoad = function () 
 };
 
 LoadVars.prototype.onData = function (src) {
+  this.loaded = true;
   if (src != null) {
     this.decode (src);
-    this.loaded = true;
     this.onLoad (true);
   } else {
     this.onLoad (false);
@@ -123,4 +120,4 @@ LoadVars.prototype.getBytesTotal = funct
   return this._bytesTotal;
 };
 
-ASSetPropFlags(LoadVars.prototype, null, 132);
+ASSetPropFlags(LoadVars.prototype, null, 1);
diff --git a/libswfdec/swfdec_initialize.h b/libswfdec/swfdec_initialize.h
index 724ce85..c991bc5 100644
--- a/libswfdec/swfdec_initialize.h
+++ b/libswfdec/swfdec_initialize.h
@@ -30,16 +30,16 @@ const unsigned char swfdec_initialize[] 
   0x53, 0x74, 0x61, 0x67,  0x65, 0x00, 0x73, 0x63,  0x61, 0x6C, 0x65, 0x4D,  0x6F, 0x64, 0x65, 0x2C,
   0x61, 0x6C, 0x69, 0x67,  0x6E, 0x2C, 0x77, 0x69,  0x64, 0x74, 0x68, 0x2C,  0x68, 0x65, 0x69, 0x67,
   0x68, 0x74, 0x00, 0x4C,  0x6F, 0x61, 0x64, 0x56,  0x61, 0x72, 0x73, 0x00,  0x70, 0x72, 0x6F, 0x74,
-  0x6F, 0x74, 0x79, 0x70,  0x65, 0x00, 0x6C, 0x6F,  0x61, 0x64, 0x65, 0x64,  0x00, 0x5F, 0x62, 0x79,
-  0x74, 0x65, 0x73, 0x4C,  0x6F, 0x61, 0x64, 0x65,  0x64, 0x00, 0x5F, 0x62,  0x79, 0x74, 0x65, 0x73,
-  0x54, 0x6F, 0x74, 0x61,  0x6C, 0x00, 0x63, 0x6F,  0x6E, 0x74, 0x65, 0x6E,  0x74, 0x54, 0x79, 0x70,
+  0x6F, 0x74, 0x79, 0x70,  0x65, 0x00, 0x63, 0x6F,  0x6E, 0x74, 0x65, 0x6E,  0x74, 0x54, 0x79, 0x70,
   0x65, 0x00, 0x61, 0x70,  0x70, 0x6C, 0x69, 0x63,  0x61, 0x74, 0x69, 0x6F,  0x6E, 0x2F, 0x78, 0x2D,
   0x77, 0x77, 0x77, 0x2D,  0x66, 0x6F, 0x72, 0x6D,  0x2D, 0x75, 0x72, 0x6C,  0x65, 0x6E, 0x63, 0x6F,
   0x64, 0x65, 0x64, 0x00,  0x6C, 0x6F, 0x61, 0x64,  0x00, 0x64, 0x65, 0x63,  0x6F, 0x64, 0x65, 0x00,
-  0x6F, 0x6E, 0x4C, 0x6F,  0x61, 0x64, 0x00, 0x6F,  0x6E, 0x44, 0x61, 0x74,  0x61, 0x00, 0x73, 0x72,
-  0x63, 0x00, 0x74, 0x6F,  0x53, 0x74, 0x72, 0x69,  0x6E, 0x67, 0x00, 0x73,  0x74, 0x72, 0x00, 0x65,
-  0x73, 0x63, 0x61, 0x70,  0x65, 0x00, 0x3D, 0x00,  0x26, 0x00, 0x67, 0x65,  0x74, 0x42, 0x79, 0x74,
-  0x65, 0x73, 0x4C, 0x6F,  0x61, 0x64, 0x65, 0x64,  0x00, 0x67, 0x65, 0x74,  0x42, 0x79, 0x74, 0x65,
+  0x6F, 0x6E, 0x4C, 0x6F,  0x61, 0x64, 0x00, 0x6F,  0x6E, 0x44, 0x61, 0x74,  0x61, 0x00, 0x6C, 0x6F,
+  0x61, 0x64, 0x65, 0x64,  0x00, 0x73, 0x72, 0x63,  0x00, 0x74, 0x6F, 0x53,  0x74, 0x72, 0x69, 0x6E,
+  0x67, 0x00, 0x73, 0x74,  0x72, 0x00, 0x65, 0x73,  0x63, 0x61, 0x70, 0x65,  0x00, 0x3D, 0x00, 0x26,
+  0x00, 0x67, 0x65, 0x74,  0x42, 0x79, 0x74, 0x65,  0x73, 0x4C, 0x6F, 0x61,  0x64, 0x65, 0x64, 0x00,
+  0x5F, 0x62, 0x79, 0x74,  0x65, 0x73, 0x4C, 0x6F,  0x61, 0x64, 0x65, 0x64,  0x00, 0x67, 0x65, 0x74,
+  0x42, 0x79, 0x74, 0x65,  0x73, 0x54, 0x6F, 0x74,  0x61, 0x6C, 0x00, 0x5F,  0x62, 0x79, 0x74, 0x65,
   0x73, 0x54, 0x6F, 0x74,  0x61, 0x6C, 0x00, 0x9B,  0x12, 0x00, 0x41, 0x73,  0x42, 0x72, 0x6F, 0x61,
   0x64, 0x63, 0x61, 0x73,  0x74, 0x65, 0x72, 0x00,  0x00, 0x00, 0x00, 0x00,  0x9B, 0x0D, 0x00, 0x4C,
   0x6F, 0x61, 0x64, 0x56,  0x61, 0x72, 0x73, 0x00,  0x00, 0x00, 0x00, 0x00,  0x96, 0x13, 0x00, 0x08,
@@ -98,43 +98,40 @@ const unsigned char swfdec_initialize[] 
   0x02, 0x00, 0x08, 0x0F,  0x52, 0x17, 0x96, 0x0E,  0x00, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x2E,
   0x07, 0x9A, 0x02, 0x00,  0x00, 0x08, 0x2D, 0x1C,  0x96, 0x07, 0x00, 0x07,  0x04, 0x00, 0x00, 0x00,
   0x08, 0x02, 0x3D, 0x17,  0x96, 0x02, 0x00, 0x08,  0x2F, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x30, 0x4E,
-  0x96, 0x03, 0x00, 0x08,  0x31, 0x03, 0x4F, 0x96,  0x02, 0x00, 0x08, 0x2F,  0x1C, 0x96, 0x02, 0x00,
-  0x08, 0x30, 0x4E, 0x96,  0x03, 0x00, 0x08, 0x32,  0x03, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x2F, 0x1C,
-  0x96, 0x02, 0x00, 0x08,  0x30, 0x4E, 0x96, 0x03,  0x00, 0x08, 0x33, 0x03,  0x4F, 0x96, 0x02, 0x00,
-  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x04, 0x00,  0x08, 0x34, 0x08, 0x35,
-  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x13, 0x00,
-  0x08, 0x36, 0x07, 0x00,  0x00, 0x00, 0x00, 0x07,  0x2D, 0x01, 0x00, 0x00,  0x07, 0x02, 0x00, 0x00,
-  0x00, 0x08, 0x01, 0x3D,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,
-  0x4E, 0x96, 0x13, 0x00,  0x08, 0x37, 0x07, 0x03,  0x00, 0x00, 0x00, 0x07,  0x2D, 0x01, 0x00, 0x00,
-  0x07, 0x02, 0x00, 0x00,  0x00, 0x08, 0x01, 0x3D,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,
-  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x02, 0x00,  0x08, 0x38, 0x9B, 0x05,  0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x4F, 0x96,  0x02, 0x00, 0x08, 0x2F,  0x1C, 0x96, 0x02, 0x00,  0x08, 0x30, 0x4E, 0x96,
-  0x02, 0x00, 0x08, 0x39,  0x9B, 0x09, 0x00, 0x00,  0x01, 0x00, 0x73, 0x72,  0x63, 0x00, 0x64, 0x00,
-  0x96, 0x02, 0x00, 0x08,  0x3A, 0x1C, 0x96, 0x01,  0x00, 0x02, 0x49, 0x12,  0x9D, 0x02, 0x00, 0x19,
-  0x00, 0x96, 0x09, 0x00,  0x05, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x08,  0x06, 0x1C, 0x96, 0x02,
-  0x00, 0x08, 0x38, 0x52,  0x17, 0x99, 0x02, 0x00,  0x3A, 0x00, 0x96, 0x02,  0x00, 0x08, 0x3A, 0x1C,
-  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x06, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x37,
-  0x52, 0x17, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x04, 0x00, 0x08,  0x31, 0x05, 0x01, 0x4F,
-  0x96, 0x09, 0x00, 0x05,  0x01, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x06,  0x1C, 0x96, 0x02, 0x00,
-  0x08, 0x38, 0x52, 0x17,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,
-  0x4E, 0x96, 0x02, 0x00,  0x08, 0x3B, 0x9B, 0x05,  0x00, 0x00, 0x00, 0x00,  0xB3, 0x00, 0x96, 0x03,
-  0x00, 0x08, 0x3C, 0x02,  0x3C, 0x96, 0x02, 0x00,  0x08, 0x06, 0x46, 0x87,  0x01, 0x00, 0x00, 0x96,
-  0x01, 0x00, 0x02, 0x49,  0x9D, 0x02, 0x00, 0x91,  0x00, 0x96, 0x04, 0x00,  0x08, 0x07, 0x04, 0x00,
-  0x3C, 0x96, 0x02, 0x00,  0x08, 0x3C, 0x1C, 0x96,  0x01, 0x00, 0x02, 0x49,  0x9D, 0x02, 0x00, 0x41,
-  0x00, 0x96, 0x02, 0x00,  0x08, 0x3C, 0x4C, 0x1C,  0x96, 0x04, 0x00, 0x08,  0x3F, 0x08, 0x07, 0x1C,
-  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x3D, 0x3D, 0x47,  0x96, 0x02, 0x00, 0x08,
-  0x3E, 0x47, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x07, 0x1C, 0x4E, 0x96,
-  0x07, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x08,  0x3D, 0x3D, 0x47, 0x47,  0x1D, 0x99, 0x02, 0x00,
-  0x33, 0x00, 0x96, 0x04,  0x00, 0x08, 0x3C, 0x08,  0x07, 0x1C, 0x96, 0x07,  0x00, 0x07, 0x01, 0x00,
-  0x00, 0x00, 0x08, 0x3D,  0x3D, 0x96, 0x02, 0x00,  0x08, 0x3E, 0x47, 0x96,  0x02, 0x00, 0x08, 0x06,
-  0x1C, 0x96, 0x02, 0x00,  0x08, 0x07, 0x1C, 0x4E,  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,
-  0x08, 0x3D, 0x3D, 0x47,  0x1D, 0x99, 0x02, 0x00,  0x61, 0xFF, 0x96, 0x02,  0x00, 0x08, 0x3C, 0x1C,
-  0x3E, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x2F, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x30, 0x4E, 0x96, 0x02,
-  0x00, 0x08, 0x40, 0x9B,  0x05, 0x00, 0x00, 0x00,  0x00, 0x0D, 0x00, 0x96,  0x02, 0x00, 0x08, 0x06,
-  0x1C, 0x96, 0x02, 0x00,  0x08, 0x32, 0x4E, 0x3E,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,
-  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x02, 0x00,  0x08, 0x41, 0x9B, 0x05,  0x00, 0x00, 0x00, 0x00,
-  0x0D, 0x00, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x33, 0x4E, 0x3E, 0x4F,
-  0x96, 0x08, 0x00, 0x07,  0x84, 0x00, 0x00, 0x00,  0x02, 0x08, 0x2F, 0x1C,  0x96, 0x02, 0x00, 0x08,
-  0x30, 0x4E, 0x96, 0x07,  0x00, 0x07, 0x03, 0x00,  0x00, 0x00, 0x08, 0x13,  0x3D, 0x17, 0x00
+  0x96, 0x04, 0x00, 0x08,  0x31, 0x08, 0x32, 0x4F,  0x96, 0x02, 0x00, 0x08,  0x2F, 0x1C, 0x96, 0x02,
+  0x00, 0x08, 0x30, 0x4E,  0x96, 0x13, 0x00, 0x08,  0x33, 0x07, 0x00, 0x00,  0x00, 0x00, 0x07, 0x2D,
+  0x01, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,  0x08, 0x01, 0x3D, 0x4F,  0x96, 0x02, 0x00, 0x08,
+  0x2F, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x30, 0x4E,  0x96, 0x13, 0x00, 0x08,  0x34, 0x07, 0x03, 0x00,
+  0x00, 0x00, 0x07, 0x2D,  0x01, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,  0x08, 0x01, 0x3D, 0x4F,
+  0x96, 0x02, 0x00, 0x08,  0x2F, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x30, 0x4E,  0x96, 0x02, 0x00, 0x08,
+  0x35, 0x9B, 0x05, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x2F, 0x1C,
+  0x96, 0x02, 0x00, 0x08,  0x30, 0x4E, 0x96, 0x02,  0x00, 0x08, 0x36, 0x9B,  0x09, 0x00, 0x00, 0x01,
+  0x00, 0x73, 0x72, 0x63,  0x00, 0x64, 0x00, 0x96,  0x02, 0x00, 0x08, 0x06,  0x1C, 0x96, 0x04, 0x00,
+  0x08, 0x37, 0x05, 0x01,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x38, 0x1C, 0x96,  0x01, 0x00, 0x02, 0x49,
+  0x12, 0x9D, 0x02, 0x00,  0x19, 0x00, 0x96, 0x09,  0x00, 0x05, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,
+  0x08, 0x06, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x35,  0x52, 0x17, 0x99, 0x02,  0x00, 0x2C, 0x00, 0x96,
+  0x02, 0x00, 0x08, 0x38,  0x1C, 0x96, 0x07, 0x00,  0x07, 0x01, 0x00, 0x00,  0x00, 0x08, 0x06, 0x1C,
+  0x96, 0x02, 0x00, 0x08,  0x34, 0x52, 0x17, 0x96,  0x09, 0x00, 0x05, 0x01,  0x07, 0x01, 0x00, 0x00,
+  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x35, 0x52, 0x17, 0x4F,  0x96, 0x02, 0x00, 0x08,
+  0x2F, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x30, 0x4E,  0x96, 0x02, 0x00, 0x08,  0x39, 0x9B, 0x05, 0x00,
+  0x00, 0x00, 0x00, 0xB3,  0x00, 0x96, 0x03, 0x00,  0x08, 0x3A, 0x02, 0x3C,  0x96, 0x02, 0x00, 0x08,
+  0x06, 0x46, 0x87, 0x01,  0x00, 0x00, 0x96, 0x01,  0x00, 0x02, 0x49, 0x9D,  0x02, 0x00, 0x91, 0x00,
+  0x96, 0x04, 0x00, 0x08,  0x07, 0x04, 0x00, 0x3C,  0x96, 0x02, 0x00, 0x08,  0x3A, 0x1C, 0x96, 0x01,
+  0x00, 0x02, 0x49, 0x9D,  0x02, 0x00, 0x41, 0x00,  0x96, 0x02, 0x00, 0x08,  0x3A, 0x4C, 0x1C, 0x96,
+  0x04, 0x00, 0x08, 0x3D,  0x08, 0x07, 0x1C, 0x96,  0x07, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x08,
+  0x3B, 0x3D, 0x47, 0x96,  0x02, 0x00, 0x08, 0x3C,  0x47, 0x96, 0x02, 0x00,  0x08, 0x06, 0x1C, 0x96,
+  0x02, 0x00, 0x08, 0x07,  0x1C, 0x4E, 0x96, 0x07,  0x00, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x3B,
+  0x3D, 0x47, 0x47, 0x1D,  0x99, 0x02, 0x00, 0x33,  0x00, 0x96, 0x04, 0x00,  0x08, 0x3A, 0x08, 0x07,
+  0x1C, 0x96, 0x07, 0x00,  0x07, 0x01, 0x00, 0x00,  0x00, 0x08, 0x3B, 0x3D,  0x96, 0x02, 0x00, 0x08,
+  0x3C, 0x47, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x07, 0x1C, 0x4E, 0x96,
+  0x07, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x08,  0x3B, 0x3D, 0x47, 0x1D,  0x99, 0x02, 0x00, 0x61,
+  0xFF, 0x96, 0x02, 0x00,  0x08, 0x3A, 0x1C, 0x3E,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,
+  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x02, 0x00,  0x08, 0x3E, 0x9B, 0x05,  0x00, 0x00, 0x00, 0x00,
+  0x0D, 0x00, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x3F, 0x4E, 0x3E, 0x4F,
+  0x96, 0x02, 0x00, 0x08,  0x2F, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x30, 0x4E,  0x96, 0x02, 0x00, 0x08,
+  0x40, 0x9B, 0x05, 0x00,  0x00, 0x00, 0x00, 0x0D,  0x00, 0x96, 0x02, 0x00,  0x08, 0x06, 0x1C, 0x96,
+  0x02, 0x00, 0x08, 0x41,  0x4E, 0x3E, 0x4F, 0x96,  0x08, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x02,
+  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x07, 0x00,  0x07, 0x03, 0x00, 0x00,
+  0x00, 0x08, 0x13, 0x3D,  0x17, 0x00
 };
 
diff --git a/test/trace/loadvars-5.swf b/test/trace/loadvars-5.swf
index 3bc1fc1..1c89902 100644
Binary files a/test/trace/loadvars-5.swf and b/test/trace/loadvars-5.swf differ
diff --git a/test/trace/loadvars-6.swf b/test/trace/loadvars-6.swf
index 992d61a..5d623a9 100644
Binary files a/test/trace/loadvars-6.swf and b/test/trace/loadvars-6.swf differ
diff --git a/test/trace/loadvars-6.swf.trace b/test/trace/loadvars-6.swf.trace
index c9d22b4..093c6d0 100644
--- a/test/trace/loadvars-6.swf.trace
+++ b/test/trace/loadvars-6.swf.trace
@@ -1,16 +1,39 @@
 [type Function]
 undefined
+onData: test=2&moi=terve&tyhja&=taysi&hehe=jotain%20muuta&hehe2=jotain muuta&on=lal=lel=luu
+
+false
+84
+84
+onLoad: true
+true
+84
+84
+hehe = jotain muuta
+hehe2 = jotain muuta
+moi = terve
+on = lal=lel=luu
+
+onData = [type Function]
+onDataReal = [type Function]
+onLoad = [type Function]
+test = 2
+tyhja = 
+onData: 
 true
+84
+84
+onLoad: false
 true
 84
 84
-on=lal%3Dlel%3Dluu%0A&hehe2=jotain%20muuta&hehe=jotain%20muuta&tyhja=&moi=terve&test=2&onLoad=%5Btype%20Function%5D
---
 hehe = jotain muuta
 hehe2 = jotain muuta
 moi = terve
 on = lal=lel=luu
 
+onData = [type Function]
+onDataReal = [type Function]
 onLoad = [type Function]
 test = 2
 tyhja = 
diff --git a/test/trace/loadvars-7.swf b/test/trace/loadvars-7.swf
index 9f9b76f..7af6ca7 100644
Binary files a/test/trace/loadvars-7.swf and b/test/trace/loadvars-7.swf differ
diff --git a/test/trace/loadvars-7.swf.trace b/test/trace/loadvars-7.swf.trace
index c9d22b4..11f965b 100644
--- a/test/trace/loadvars-7.swf.trace
+++ b/test/trace/loadvars-7.swf.trace
@@ -1,16 +1,39 @@
 [type Function]
 undefined
+onData: test=2&moi=terve&tyhja&=taysi&hehe=jotain%20muuta&hehe2=jotain muuta&on=lal=lel=luu
+
+false
+84
+84
+onLoad: true
+true
+84
+84
+hehe = jotain muuta
+hehe2 = jotain muuta
+moi = terve
+on = lal=lel=luu
+
+onData = [type Function]
+onDataReal = [type Function]
+onLoad = [type Function]
+test = 2
+tyhja = 
+onData: undefined
 true
+84
+84
+onLoad: false
 true
 84
 84
-on=lal%3Dlel%3Dluu%0A&hehe2=jotain%20muuta&hehe=jotain%20muuta&tyhja=&moi=terve&test=2&onLoad=%5Btype%20Function%5D
---
 hehe = jotain muuta
 hehe2 = jotain muuta
 moi = terve
 on = lal=lel=luu
 
+onData = [type Function]
+onDataReal = [type Function]
 onLoad = [type Function]
 test = 2
 tyhja = 
diff --git a/test/trace/loadvars.as b/test/trace/loadvars.as
index 778615d..b21ea99 100644
--- a/test/trace/loadvars.as
+++ b/test/trace/loadvars.as
@@ -1,23 +1,25 @@
 // makeswf -v 7 -r 1 -o loadvars-7.swf loadvars.as
 
-//_global.unescape = function () { return "moi"; };
-//_global.escape = function () { return "moi"; };
-
 var lv = new LoadVars ();
 
 trace (lv.onLoad);
 trace (lv.loaded);
 
+lv.onDataReal = lv.onData;
+lv.onData = function (src) {
+  trace ("onData: " + src);
+  trace (this.loaded);
+  trace (this._bytesLoaded);
+  trace (this._bytesTotal);
+  lv.onDataReal (src);
+};
+
 lv.onLoad = function (success) {
-  trace (success);
+  trace ("onLoad: " + success);
   trace (this.loaded);
   trace (this._bytesLoaded);
   trace (this._bytesTotal);
-  trace (this);
-  trace ("--");
   var props = new Array ();
-  //ASSetPropFlags (this, null, 0, 1);
-  //ASSetPropFlags (this.__proto__, null, 0, 1);
   for (var prop in this) {
     props.push (prop);
   }
@@ -28,6 +30,7 @@ lv.onLoad = function (success) {
 };
 
 lv.load ("params.txt");
+lv.load ("blah.txt");
 
 function quit () {
   loadMovie ("FSCommand:quit", "");
diff-tree b73fa2d44918c74e7ea8797f9f54a61b63b80245 (from 51dbe7d127eca9614957017d866adaa30244658d)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 12:14:54 2007 +0300

    Make LoadObject set loaded property to false, update test

diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index 7674f3b..ce5a4de 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -252,6 +252,7 @@ const char swfdec_as_strings[] = 
   SWFDEC_AS_CONSTANT_STRING ("close")
   SWFDEC_AS_CONSTANT_STRING ("_bytesLoaded")
   SWFDEC_AS_CONSTANT_STRING ("_bytesTotal")
+  SWFDEC_AS_CONSTANT_STRING ("loaded")
   /* add more here */
 ;
 
diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
index 2b19f07..4d00a61 100644
--- a/libswfdec/swfdec_load_object.c
+++ b/libswfdec/swfdec_load_object.c
@@ -188,6 +188,10 @@ swfdec_load_object_load (SwfdecLoadObjec
   SWFDEC_AS_VALUE_SET_INT (&val, 0);
   swfdec_as_object_set_variable_and_flags (load_object->target,
       SWFDEC_AS_STR__bytesLoaded, &val, SWFDEC_AS_VARIABLE_HIDDEN);
+
+  SWFDEC_AS_VALUE_SET_BOOLEAN (&val, FALSE);
+  swfdec_as_object_set_variable_and_flags (load_object->target,
+      SWFDEC_AS_STR_loaded, &val, SWFDEC_AS_VARIABLE_HIDDEN);
 }
 
 SwfdecAsObject *
diff --git a/test/trace/loadobject-5.swf b/test/trace/loadobject-5.swf
index b3b144d..ae9765b 100644
Binary files a/test/trace/loadobject-5.swf and b/test/trace/loadobject-5.swf differ
diff --git a/test/trace/loadobject-5.swf.trace b/test/trace/loadobject-5.swf.trace
index ba49d21..cee074b 100644
--- a/test/trace/loadobject-5.swf.trace
+++ b/test/trace/loadobject-5.swf.trace
@@ -1,14 +1,18 @@
 Loaded: 
 Total: 
+Is loaded: 
 false
 Loaded: 
 Total: 
+Is loaded: 
 true
 Loaded: 0
 Total: 
+Is loaded: false
 true
 Loaded: 0
 Total: 
+Is loaded: false
 Got: string '// makeswf -v 7 -r 1 -o loadobject-7.swf loadobject.as
 
 var obj = new Object ();
@@ -19,19 +23,24 @@ obj.onData = function (str) {
   trace ("Got: " + typeof (str) + " '" + str + "'");
   trace ("Loaded: " + this._bytesLoaded);
   trace ("Total: " + this._bytesTotal);
+  trace ("Is loaded: " + obj.loaded);
 };
 
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ());
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("loadobject.as"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("404"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 
 function quit () {
   loadMovie ("FSCommand:quit", "");
@@ -39,8 +48,10 @@ function quit () {
 
 setInterval (quit, 1000);
 '
-Loaded: 755
-Total: 755
+Loaded: 937
+Total: 937
+Is loaded: false
 Got: undefined ''
-Loaded: 755
-Total: 755
+Loaded: 937
+Total: 937
+Is loaded: false
diff --git a/test/trace/loadobject-6.swf b/test/trace/loadobject-6.swf
index 3a19ff4..c7b3f43 100644
Binary files a/test/trace/loadobject-6.swf and b/test/trace/loadobject-6.swf differ
diff --git a/test/trace/loadobject-6.swf.trace b/test/trace/loadobject-6.swf.trace
index ba49d21..cee074b 100644
--- a/test/trace/loadobject-6.swf.trace
+++ b/test/trace/loadobject-6.swf.trace
@@ -1,14 +1,18 @@
 Loaded: 
 Total: 
+Is loaded: 
 false
 Loaded: 
 Total: 
+Is loaded: 
 true
 Loaded: 0
 Total: 
+Is loaded: false
 true
 Loaded: 0
 Total: 
+Is loaded: false
 Got: string '// makeswf -v 7 -r 1 -o loadobject-7.swf loadobject.as
 
 var obj = new Object ();
@@ -19,19 +23,24 @@ obj.onData = function (str) {
   trace ("Got: " + typeof (str) + " '" + str + "'");
   trace ("Loaded: " + this._bytesLoaded);
   trace ("Total: " + this._bytesTotal);
+  trace ("Is loaded: " + obj.loaded);
 };
 
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ());
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("loadobject.as"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("404"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 
 function quit () {
   loadMovie ("FSCommand:quit", "");
@@ -39,8 +48,10 @@ function quit () {
 
 setInterval (quit, 1000);
 '
-Loaded: 755
-Total: 755
+Loaded: 937
+Total: 937
+Is loaded: false
 Got: undefined ''
-Loaded: 755
-Total: 755
+Loaded: 937
+Total: 937
+Is loaded: false
diff --git a/test/trace/loadobject-7.swf b/test/trace/loadobject-7.swf
index 4d580e6..b6aaf29 100644
Binary files a/test/trace/loadobject-7.swf and b/test/trace/loadobject-7.swf differ
diff --git a/test/trace/loadobject-7.swf.trace b/test/trace/loadobject-7.swf.trace
index 8e6d8c0..48b10f4 100644
--- a/test/trace/loadobject-7.swf.trace
+++ b/test/trace/loadobject-7.swf.trace
@@ -1,14 +1,18 @@
 Loaded: undefined
 Total: undefined
+Is loaded: undefined
 false
 Loaded: undefined
 Total: undefined
+Is loaded: undefined
 true
 Loaded: 0
 Total: undefined
+Is loaded: false
 true
 Loaded: 0
 Total: undefined
+Is loaded: false
 Got: string '// makeswf -v 7 -r 1 -o loadobject-7.swf loadobject.as
 
 var obj = new Object ();
@@ -19,19 +23,24 @@ obj.onData = function (str) {
   trace ("Got: " + typeof (str) + " '" + str + "'");
   trace ("Loaded: " + this._bytesLoaded);
   trace ("Total: " + this._bytesTotal);
+  trace ("Is loaded: " + obj.loaded);
 };
 
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ());
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("loadobject.as"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("404"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 
 function quit () {
   loadMovie ("FSCommand:quit", "");
@@ -39,8 +48,10 @@ function quit () {
 
 setInterval (quit, 1000);
 '
-Loaded: 755
-Total: 755
+Loaded: 937
+Total: 937
+Is loaded: false
 Got: undefined 'undefined'
-Loaded: 755
-Total: 755
+Loaded: 937
+Total: 937
+Is loaded: false
diff --git a/test/trace/loadobject.as b/test/trace/loadobject.as
index 127e063..62acf8a 100644
--- a/test/trace/loadobject.as
+++ b/test/trace/loadobject.as
@@ -8,19 +8,24 @@ obj.onData = function (str) {
   trace ("Got: " + typeof (str) + " '" + str + "'");
   trace ("Loaded: " + this._bytesLoaded);
   trace ("Total: " + this._bytesTotal);
+  trace ("Is loaded: " + obj.loaded);
 };
 
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ());
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("loadobject.as"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 trace (obj.load ("404"));
 trace ("Loaded: " + obj._bytesLoaded);
 trace ("Total: " + obj._bytesTotal);
+trace ("Is loaded: " + obj.loaded);
 
 function quit () {
   loadMovie ("FSCommand:quit", "");
diff-tree 51dbe7d127eca9614957017d866adaa30244658d (from f3fafaa0f2c241b4c42c0f436cfe438d9ab3eadf)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 11:41:53 2007 +0300

    Fix unescape in version 5 I just broke

diff --git a/libswfdec/swfdec_as_string.c b/libswfdec/swfdec_as_string.c
index a200a22..720bc5c 100644
--- a/libswfdec/swfdec_as_string.c
+++ b/libswfdec/swfdec_as_string.c
@@ -523,7 +523,7 @@ swfdec_as_string_unescape_5 (SwfdecAsCon
   } else {
     g_warning ("can't convert %s to UTF-8", msg);
     g_free (out);
-    return NULL;
+    return g_strdup ("");
   }
 #undef APPEND
 }
@@ -655,7 +655,7 @@ swfdec_as_string_unescape_6 (SwfdecAsCon
   } else {
     g_warning ("%s unescaped is invalid UTF-8", msg);
     g_byte_array_free (array, TRUE);
-    return NULL;
+    return g_strdup ("");
   }
 #undef APPEND
 }
@@ -680,11 +680,10 @@ swfdec_as_string_unescape_internal (Swfd
     swfdec_as_string_unescape (cx, swfdec_as_value_to_string (cx, &argv[0]));
   if (result != NULL) {
     SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_get_string (cx, result));
+    g_free (result);
   } else {
-    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY);
+    SWFDEC_AS_VALUE_SET_UNDEFINED (ret);
   }
-
-  g_free (result);
 }
 
 void
diff-tree f3fafaa0f2c241b4c42c0f436cfe438d9ab3eadf (from 4c3971ef059f0f7a8c135250b60546170564175f)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 11:16:57 2007 +0300

    Add test case for LoadVars

diff --git a/test/trace/loadvars-5.swf b/test/trace/loadvars-5.swf
new file mode 100644
index 0000000..3bc1fc1
Binary files /dev/null and b/test/trace/loadvars-5.swf differ
diff --git a/test/trace/loadvars-5.swf.trace b/test/trace/loadvars-5.swf.trace
new file mode 100644
index 0000000..d4f80bf
--- /dev/null
+++ b/test/trace/loadvars-5.swf.trace
@@ -0,0 +1,2 @@
+undefined
+undefined
diff --git a/test/trace/loadvars-6.swf b/test/trace/loadvars-6.swf
new file mode 100644
index 0000000..992d61a
Binary files /dev/null and b/test/trace/loadvars-6.swf differ
diff --git a/test/trace/loadvars-6.swf.trace b/test/trace/loadvars-6.swf.trace
new file mode 100644
index 0000000..c9d22b4
--- /dev/null
+++ b/test/trace/loadvars-6.swf.trace
@@ -0,0 +1,16 @@
+[type Function]
+undefined
+true
+true
+84
+84
+on=lal%3Dlel%3Dluu%0A&hehe2=jotain%20muuta&hehe=jotain%20muuta&tyhja=&moi=terve&test=2&onLoad=%5Btype%20Function%5D
+--
+hehe = jotain muuta
+hehe2 = jotain muuta
+moi = terve
+on = lal=lel=luu
+
+onLoad = [type Function]
+test = 2
+tyhja = 
diff --git a/test/trace/loadvars-7.swf b/test/trace/loadvars-7.swf
new file mode 100644
index 0000000..9f9b76f
Binary files /dev/null and b/test/trace/loadvars-7.swf differ
diff --git a/test/trace/loadvars-7.swf.trace b/test/trace/loadvars-7.swf.trace
new file mode 100644
index 0000000..c9d22b4
--- /dev/null
+++ b/test/trace/loadvars-7.swf.trace
@@ -0,0 +1,16 @@
+[type Function]
+undefined
+true
+true
+84
+84
+on=lal%3Dlel%3Dluu%0A&hehe2=jotain%20muuta&hehe=jotain%20muuta&tyhja=&moi=terve&test=2&onLoad=%5Btype%20Function%5D
+--
+hehe = jotain muuta
+hehe2 = jotain muuta
+moi = terve
+on = lal=lel=luu
+
+onLoad = [type Function]
+test = 2
+tyhja = 
diff --git a/test/trace/loadvars.as b/test/trace/loadvars.as
new file mode 100644
index 0000000..778615d
--- /dev/null
+++ b/test/trace/loadvars.as
@@ -0,0 +1,36 @@
+// makeswf -v 7 -r 1 -o loadvars-7.swf loadvars.as
+
+//_global.unescape = function () { return "moi"; };
+//_global.escape = function () { return "moi"; };
+
+var lv = new LoadVars ();
+
+trace (lv.onLoad);
+trace (lv.loaded);
+
+lv.onLoad = function (success) {
+  trace (success);
+  trace (this.loaded);
+  trace (this._bytesLoaded);
+  trace (this._bytesTotal);
+  trace (this);
+  trace ("--");
+  var props = new Array ();
+  //ASSetPropFlags (this, null, 0, 1);
+  //ASSetPropFlags (this.__proto__, null, 0, 1);
+  for (var prop in this) {
+    props.push (prop);
+  }
+  props.sort ();
+  for (var i = 0; i < props.length; i++) {
+    trace (props[i] + " = " + this[props[i]]);
+  }
+};
+
+lv.load ("params.txt");
+
+function quit () {
+  loadMovie ("FSCommand:quit", "");
+};
+
+setInterval (quit, 1000);
diff-tree 4c3971ef059f0f7a8c135250b60546170564175f (from a7ae2ccc6a9f28b013e31293fcfa87b7c1b7fd88)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 11:16:33 2007 +0300

    Start implementing LoadVars class

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 85ec276..6d3aaaf 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -78,6 +78,7 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_load_object_as.c \
 	swfdec_loader.c \
 	swfdec_loadertarget.c \
+	swfdec_loadvars_as.c \
 	swfdec_marshal.c \
 	swfdec_morph_movie.c \
 	swfdec_morphshape.c \
diff --git a/libswfdec/swfdec_initialize.as b/libswfdec/swfdec_initialize.as
index 70f5d8d..bd6215d 100644
--- a/libswfdec/swfdec_initialize.as
+++ b/libswfdec/swfdec_initialize.as
@@ -76,3 +76,51 @@ Stage = new Object ();
 AsBroadcaster.initialize (Stage);
 ASSetNativeAccessor (Stage, 666, "scaleMode,align,width,height", 1);
 
+/*** LOADVARS ***/
+
+function LoadVars () { };
+
+LoadVars.prototype.loaded = undefined;
+LoadVars.prototype._bytesLoaded = undefined;
+LoadVars.prototype._bytesTotal = undefined;
+LoadVars.prototype.contentType = "application/x-www-form-urlencoded";
+
+LoadVars.prototype.load = ASnative (301, 0);
+//LoadVars.prototype.send = ASnative (301, 1);
+//LoadVars.prototype.sendAndLoad = ASnative (301, 2);
+LoadVars.prototype.decode = ASnative (301, 3);
+
+LoadVars.prototype.onLoad = function () {
+};
+
+LoadVars.prototype.onData = function (src) {
+  if (src != null) {
+    this.decode (src);
+    this.loaded = true;
+    this.onLoad (true);
+  } else {
+    this.onLoad (false);
+  }
+};
+
+LoadVars.prototype.toString = function () {
+  var str = null;
+  for (var x in this) {
+    if (str == null) {
+      str = escape(x) + "=" + escape(this[x]);
+    } else {
+      str += "&" + escape(x) + "=" + escape(this[x]);
+    }
+  }
+  return str;
+};
+
+LoadVars.prototype.getBytesLoaded = function () {
+  return this._bytesLoaded;
+};
+
+LoadVars.prototype.getBytesTotal = function () {
+  return this._bytesTotal;
+};
+
+ASSetPropFlags(LoadVars.prototype, null, 132);
diff --git a/libswfdec/swfdec_initialize.h b/libswfdec/swfdec_initialize.h
index 51794cb..724ce85 100644
--- a/libswfdec/swfdec_initialize.h
+++ b/libswfdec/swfdec_initialize.h
@@ -2,7 +2,7 @@
 
 /* compiled from swfdec_initialize.as */
 const unsigned char swfdec_initialize[] = {
-  0x88, 0xB0, 0x01, 0x2F,  0x00, 0x41, 0x53, 0x53,  0x65, 0x74, 0x4E, 0x61,  0x74, 0x69, 0x76, 0x65,
+  0x88, 0x64, 0x02, 0x42,  0x00, 0x41, 0x53, 0x53,  0x65, 0x74, 0x4E, 0x61,  0x74, 0x69, 0x76, 0x65,
   0x00, 0x41, 0x53, 0x6E,  0x61, 0x74, 0x69, 0x76,  0x65, 0x00, 0x41, 0x53,  0x53, 0x65, 0x74, 0x4E,
   0x61, 0x74, 0x69, 0x76,  0x65, 0x41, 0x63, 0x63,  0x65, 0x73, 0x73, 0x6F,  0x72, 0x00, 0x41, 0x73,
   0x42, 0x72, 0x6F, 0x61,  0x64, 0x63, 0x61, 0x73,  0x74, 0x65, 0x72, 0x00,  0x62, 0x72, 0x6F, 0x61,
@@ -29,62 +29,112 @@ const unsigned char swfdec_initialize[] 
   0x62, 0x6A, 0x65, 0x63,  0x74, 0x00, 0x73, 0x68,  0x6F, 0x77, 0x00, 0x68,  0x69, 0x64, 0x65, 0x00,
   0x53, 0x74, 0x61, 0x67,  0x65, 0x00, 0x73, 0x63,  0x61, 0x6C, 0x65, 0x4D,  0x6F, 0x64, 0x65, 0x2C,
   0x61, 0x6C, 0x69, 0x67,  0x6E, 0x2C, 0x77, 0x69,  0x64, 0x74, 0x68, 0x2C,  0x68, 0x65, 0x69, 0x67,
-  0x68, 0x74, 0x00, 0x9B,  0x12, 0x00, 0x41, 0x73,  0x42, 0x72, 0x6F, 0x61,  0x64, 0x63, 0x61, 0x73,
-  0x74, 0x65, 0x72, 0x00,  0x00, 0x00, 0x00, 0x00,  0x96, 0x13, 0x00, 0x08,  0x00, 0x07, 0x00, 0x00,
-  0x00, 0x00, 0x07, 0x04,  0x00, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,  0x08, 0x01, 0x3D, 0x1D,
-  0x96, 0x13, 0x00, 0x08,  0x02, 0x07, 0x01, 0x00,  0x00, 0x00, 0x07, 0x04,  0x00, 0x00, 0x00, 0x07,
-  0x02, 0x00, 0x00, 0x00,  0x08, 0x01, 0x3D, 0x1D,  0x96, 0x02, 0x00, 0x08,  0x03, 0x1C, 0x96, 0x13,
-  0x00, 0x08, 0x04, 0x07,  0x0C, 0x00, 0x00, 0x00,  0x07, 0x65, 0x00, 0x00,  0x00, 0x07, 0x02, 0x00,
-  0x00, 0x00, 0x08, 0x01,  0x3D, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x03, 0x1C,  0x96, 0x02, 0x00, 0x08,
-  0x05, 0x9B, 0x07, 0x00,  0x00, 0x01, 0x00, 0x78,  0x00, 0x3C, 0x00, 0x96,  0x02, 0x00, 0x08, 0x07,
-  0x1C, 0x96, 0x07, 0x00,  0x07, 0x01, 0x00, 0x00,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,
-  0x08, 0x52, 0x17, 0x96,  0x02, 0x00, 0x08, 0x07,  0x1C, 0x96, 0x07, 0x00,  0x07, 0x01, 0x00, 0x00,
-  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x09, 0x4E, 0x96, 0x02,  0x00, 0x08, 0x0A, 0x52,
-  0x17, 0x96, 0x02, 0x00,  0x05, 0x01, 0x3E, 0x4F,  0x96, 0x02, 0x00, 0x08,  0x03, 0x1C, 0x96, 0x02,
-  0x00, 0x08, 0x08, 0x9B,  0x07, 0x00, 0x00, 0x01,  0x00, 0x78, 0x00, 0x8F,  0x00, 0x96, 0x04, 0x00,
-  0x08, 0x0B, 0x08, 0x06,  0x1C, 0x96, 0x02, 0x00,  0x08, 0x09, 0x4E, 0x3C,  0x96, 0x02, 0x00, 0x08,
-  0x0C, 0x41, 0x96, 0x07,  0x00, 0x08, 0x0C, 0x07,  0x00, 0x00, 0x00, 0x00,  0x3C, 0x99, 0x02, 0x00,
-  0x09, 0x00, 0x96, 0x02,  0x00, 0x08, 0x0C, 0x4C,  0x1C, 0x50, 0x1D, 0x96,  0x02, 0x00, 0x08, 0x0C,
-  0x1C, 0x96, 0x02, 0x00,  0x08, 0x0B, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x0D,  0x4E, 0x48, 0x12, 0x9D,
-  0x02, 0x00, 0x42, 0x00,  0x96, 0x02, 0x00, 0x08,  0x0B, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x0C, 0x1C,
-  0x4E, 0x96, 0x02, 0x00,  0x08, 0x07, 0x1C, 0x49,  0x12, 0x9D, 0x02, 0x00,  0x23, 0x00, 0x96, 0x07,
-  0x00, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x0C,  0x1C, 0x96, 0x07, 0x00,  0x07, 0x02, 0x00, 0x00,
-  0x00, 0x08, 0x0B, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x0E, 0x52, 0x17, 0x96,  0x02, 0x00, 0x05, 0x01,
-  0x3E, 0x99, 0x02, 0x00,  0x9C, 0xFF, 0x96, 0x02,  0x00, 0x05, 0x00, 0x3E,  0x4F, 0x96, 0x02, 0x00,
-  0x08, 0x03, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x0F,  0x9B, 0x07, 0x00, 0x00,  0x01, 0x00, 0x6F, 0x00,
-  0x75, 0x00, 0x96, 0x02,  0x00, 0x08, 0x10, 0x1C,  0x96, 0x13, 0x00, 0x08,  0x04, 0x07, 0x0C, 0x00,
-  0x00, 0x00, 0x07, 0x65,  0x00, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,  0x08, 0x01, 0x3D, 0x4F,
-  0x96, 0x02, 0x00, 0x08,  0x10, 0x1C, 0x96, 0x04,  0x00, 0x08, 0x05, 0x08,  0x03, 0x1C, 0x96, 0x02,
-  0x00, 0x08, 0x05, 0x4E,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x10, 0x1C, 0x96,  0x04, 0x00, 0x08, 0x08,
-  0x08, 0x03, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x08,  0x4E, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x10, 0x1C,
-  0x96, 0x09, 0x00, 0x08,  0x09, 0x07, 0x00, 0x00,  0x00, 0x00, 0x08, 0x11,  0x40, 0x4F, 0x96, 0x09,
-  0x00, 0x07, 0x83, 0x00,  0x00, 0x00, 0x08, 0x12,  0x08, 0x10, 0x1C, 0x96,  0x07, 0x00, 0x07, 0x03,
-  0x00, 0x00, 0x00, 0x08,  0x13, 0x3D, 0x17, 0x4F,  0x96, 0x08, 0x00, 0x07,  0x83, 0x00, 0x00, 0x00,
-  0x02, 0x08, 0x03, 0x1C,  0x96, 0x07, 0x00, 0x07,  0x03, 0x00, 0x00, 0x00,  0x08, 0x13, 0x3D, 0x17,
-  0x96, 0x8C, 0x00, 0x08,  0x14, 0x08, 0x15, 0x07,  0x12, 0x00, 0x00, 0x00,  0x08, 0x16, 0x07, 0x08,
-  0x00, 0x00, 0x00, 0x08,  0x17, 0x07, 0x14, 0x00,  0x00, 0x00, 0x08, 0x18,  0x07, 0x11, 0x00, 0x00,
-  0x00, 0x08, 0x19, 0x07,  0x2E, 0x00, 0x00, 0x00,  0x08, 0x1A, 0x07, 0x28,  0x00, 0x00, 0x00, 0x08,
-  0x1B, 0x07, 0x23, 0x00,  0x00, 0x00, 0x08, 0x1C,  0x07, 0x0D, 0x00, 0x00,  0x00, 0x08, 0x1D, 0x07,
-  0x1B, 0x00, 0x00, 0x00,  0x08, 0x1E, 0x07, 0x24,  0x00, 0x00, 0x00, 0x08,  0x1F, 0x07, 0x2D, 0x00,
-  0x00, 0x00, 0x08, 0x20,  0x07, 0x25, 0x00, 0x00,  0x00, 0x08, 0x21, 0x07,  0x22, 0x00, 0x00, 0x00,
-  0x08, 0x22, 0x07, 0x21,  0x00, 0x00, 0x00, 0x08,  0x23, 0x07, 0x27, 0x00,  0x00, 0x00, 0x08, 0x24,
-  0x07, 0x10, 0x00, 0x00,  0x00, 0x08, 0x25, 0x07,  0x20, 0x00, 0x00, 0x00,  0x08, 0x26, 0x07, 0x09,
-  0x00, 0x00, 0x00, 0x08,  0x27, 0x07, 0x26, 0x00,  0x00, 0x00, 0x07, 0x13,  0x00, 0x00, 0x00, 0x43,
-  0x1D, 0x96, 0x09, 0x00,  0x08, 0x28, 0x07, 0x20,  0x03, 0x00, 0x00, 0x08,  0x14, 0x1C, 0x96, 0x07,
-  0x00, 0x07, 0x03, 0x00,  0x00, 0x00, 0x08, 0x00,  0x3D, 0x17, 0x96, 0x02,  0x00, 0x08, 0x14, 0x1C,
-  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x03, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x0F,
-  0x52, 0x17, 0x96, 0x08,  0x00, 0x07, 0x07, 0x00,  0x00, 0x00, 0x02, 0x08,  0x14, 0x1C, 0x96, 0x07,
-  0x00, 0x07, 0x03, 0x00,  0x00, 0x00, 0x08, 0x13,  0x3D, 0x17, 0x96, 0x09,  0x00, 0x08, 0x29, 0x07,
-  0x00, 0x00, 0x00, 0x00,  0x08, 0x2A, 0x40, 0x1D,  0x96, 0x02, 0x00, 0x08,  0x29, 0x1C, 0x96, 0x13,
-  0x00, 0x08, 0x2B, 0x07,  0x00, 0x00, 0x00, 0x00,  0x07, 0x05, 0x00, 0x00,  0x00, 0x07, 0x02, 0x00,
-  0x00, 0x00, 0x08, 0x01,  0x3D, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x29, 0x1C,  0x96, 0x13, 0x00, 0x08,
-  0x2C, 0x07, 0x01, 0x00,  0x00, 0x00, 0x07, 0x05,  0x00, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,
-  0x08, 0x01, 0x3D, 0x4F,  0x96, 0x02, 0x00, 0x08,  0x29, 0x1C, 0x96, 0x07,  0x00, 0x07, 0x01, 0x00,
-  0x00, 0x00, 0x08, 0x03,  0x1C, 0x96, 0x02, 0x00,  0x08, 0x0F, 0x52, 0x17,  0x96, 0x09, 0x00, 0x08,
-  0x2D, 0x07, 0x00, 0x00,  0x00, 0x00, 0x08, 0x2A,  0x40, 0x1D, 0x96, 0x02,  0x00, 0x08, 0x2D, 0x1C,
-  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x03, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x0F,
-  0x52, 0x17, 0x96, 0x0E,  0x00, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x2E,  0x07, 0x9A, 0x02, 0x00,
-  0x00, 0x08, 0x2D, 0x1C,  0x96, 0x07, 0x00, 0x07,  0x04, 0x00, 0x00, 0x00,  0x08, 0x02, 0x3D, 0x17,
-  0x00
+  0x68, 0x74, 0x00, 0x4C,  0x6F, 0x61, 0x64, 0x56,  0x61, 0x72, 0x73, 0x00,  0x70, 0x72, 0x6F, 0x74,
+  0x6F, 0x74, 0x79, 0x70,  0x65, 0x00, 0x6C, 0x6F,  0x61, 0x64, 0x65, 0x64,  0x00, 0x5F, 0x62, 0x79,
+  0x74, 0x65, 0x73, 0x4C,  0x6F, 0x61, 0x64, 0x65,  0x64, 0x00, 0x5F, 0x62,  0x79, 0x74, 0x65, 0x73,
+  0x54, 0x6F, 0x74, 0x61,  0x6C, 0x00, 0x63, 0x6F,  0x6E, 0x74, 0x65, 0x6E,  0x74, 0x54, 0x79, 0x70,
+  0x65, 0x00, 0x61, 0x70,  0x70, 0x6C, 0x69, 0x63,  0x61, 0x74, 0x69, 0x6F,  0x6E, 0x2F, 0x78, 0x2D,
+  0x77, 0x77, 0x77, 0x2D,  0x66, 0x6F, 0x72, 0x6D,  0x2D, 0x75, 0x72, 0x6C,  0x65, 0x6E, 0x63, 0x6F,
+  0x64, 0x65, 0x64, 0x00,  0x6C, 0x6F, 0x61, 0x64,  0x00, 0x64, 0x65, 0x63,  0x6F, 0x64, 0x65, 0x00,
+  0x6F, 0x6E, 0x4C, 0x6F,  0x61, 0x64, 0x00, 0x6F,  0x6E, 0x44, 0x61, 0x74,  0x61, 0x00, 0x73, 0x72,
+  0x63, 0x00, 0x74, 0x6F,  0x53, 0x74, 0x72, 0x69,  0x6E, 0x67, 0x00, 0x73,  0x74, 0x72, 0x00, 0x65,
+  0x73, 0x63, 0x61, 0x70,  0x65, 0x00, 0x3D, 0x00,  0x26, 0x00, 0x67, 0x65,  0x74, 0x42, 0x79, 0x74,
+  0x65, 0x73, 0x4C, 0x6F,  0x61, 0x64, 0x65, 0x64,  0x00, 0x67, 0x65, 0x74,  0x42, 0x79, 0x74, 0x65,
+  0x73, 0x54, 0x6F, 0x74,  0x61, 0x6C, 0x00, 0x9B,  0x12, 0x00, 0x41, 0x73,  0x42, 0x72, 0x6F, 0x61,
+  0x64, 0x63, 0x61, 0x73,  0x74, 0x65, 0x72, 0x00,  0x00, 0x00, 0x00, 0x00,  0x9B, 0x0D, 0x00, 0x4C,
+  0x6F, 0x61, 0x64, 0x56,  0x61, 0x72, 0x73, 0x00,  0x00, 0x00, 0x00, 0x00,  0x96, 0x13, 0x00, 0x08,
+  0x00, 0x07, 0x00, 0x00,  0x00, 0x00, 0x07, 0x04,  0x00, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,
+  0x08, 0x01, 0x3D, 0x1D,  0x96, 0x13, 0x00, 0x08,  0x02, 0x07, 0x01, 0x00,  0x00, 0x00, 0x07, 0x04,
+  0x00, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,  0x08, 0x01, 0x3D, 0x1D,  0x96, 0x02, 0x00, 0x08,
+  0x03, 0x1C, 0x96, 0x13,  0x00, 0x08, 0x04, 0x07,  0x0C, 0x00, 0x00, 0x00,  0x07, 0x65, 0x00, 0x00,
+  0x00, 0x07, 0x02, 0x00,  0x00, 0x00, 0x08, 0x01,  0x3D, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x03, 0x1C,
+  0x96, 0x02, 0x00, 0x08,  0x05, 0x9B, 0x07, 0x00,  0x00, 0x01, 0x00, 0x78,  0x00, 0x3C, 0x00, 0x96,
+  0x02, 0x00, 0x08, 0x07,  0x1C, 0x96, 0x07, 0x00,  0x07, 0x01, 0x00, 0x00,  0x00, 0x08, 0x06, 0x1C,
+  0x96, 0x02, 0x00, 0x08,  0x08, 0x52, 0x17, 0x96,  0x02, 0x00, 0x08, 0x07,  0x1C, 0x96, 0x07, 0x00,
+  0x07, 0x01, 0x00, 0x00,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x09, 0x4E, 0x96, 0x02,
+  0x00, 0x08, 0x0A, 0x52,  0x17, 0x96, 0x02, 0x00,  0x05, 0x01, 0x3E, 0x4F,  0x96, 0x02, 0x00, 0x08,
+  0x03, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x08, 0x9B,  0x07, 0x00, 0x00, 0x01,  0x00, 0x78, 0x00, 0x8F,
+  0x00, 0x96, 0x04, 0x00,  0x08, 0x0B, 0x08, 0x06,  0x1C, 0x96, 0x02, 0x00,  0x08, 0x09, 0x4E, 0x3C,
+  0x96, 0x02, 0x00, 0x08,  0x0C, 0x41, 0x96, 0x07,  0x00, 0x08, 0x0C, 0x07,  0x00, 0x00, 0x00, 0x00,
+  0x3C, 0x99, 0x02, 0x00,  0x09, 0x00, 0x96, 0x02,  0x00, 0x08, 0x0C, 0x4C,  0x1C, 0x50, 0x1D, 0x96,
+  0x02, 0x00, 0x08, 0x0C,  0x1C, 0x96, 0x02, 0x00,  0x08, 0x0B, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x0D,
+  0x4E, 0x48, 0x12, 0x9D,  0x02, 0x00, 0x42, 0x00,  0x96, 0x02, 0x00, 0x08,  0x0B, 0x1C, 0x96, 0x02,
+  0x00, 0x08, 0x0C, 0x1C,  0x4E, 0x96, 0x02, 0x00,  0x08, 0x07, 0x1C, 0x49,  0x12, 0x9D, 0x02, 0x00,
+  0x23, 0x00, 0x96, 0x07,  0x00, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x0C,  0x1C, 0x96, 0x07, 0x00,
+  0x07, 0x02, 0x00, 0x00,  0x00, 0x08, 0x0B, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x0E, 0x52, 0x17, 0x96,
+  0x02, 0x00, 0x05, 0x01,  0x3E, 0x99, 0x02, 0x00,  0x9C, 0xFF, 0x96, 0x02,  0x00, 0x05, 0x00, 0x3E,
+  0x4F, 0x96, 0x02, 0x00,  0x08, 0x03, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x0F,  0x9B, 0x07, 0x00, 0x00,
+  0x01, 0x00, 0x6F, 0x00,  0x75, 0x00, 0x96, 0x02,  0x00, 0x08, 0x10, 0x1C,  0x96, 0x13, 0x00, 0x08,
+  0x04, 0x07, 0x0C, 0x00,  0x00, 0x00, 0x07, 0x65,  0x00, 0x00, 0x00, 0x07,  0x02, 0x00, 0x00, 0x00,
+  0x08, 0x01, 0x3D, 0x4F,  0x96, 0x02, 0x00, 0x08,  0x10, 0x1C, 0x96, 0x04,  0x00, 0x08, 0x05, 0x08,
+  0x03, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x05, 0x4E,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x10, 0x1C, 0x96,
+  0x04, 0x00, 0x08, 0x08,  0x08, 0x03, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x08,  0x4E, 0x4F, 0x96, 0x02,
+  0x00, 0x08, 0x10, 0x1C,  0x96, 0x09, 0x00, 0x08,  0x09, 0x07, 0x00, 0x00,  0x00, 0x00, 0x08, 0x11,
+  0x40, 0x4F, 0x96, 0x09,  0x00, 0x07, 0x83, 0x00,  0x00, 0x00, 0x08, 0x12,  0x08, 0x10, 0x1C, 0x96,
+  0x07, 0x00, 0x07, 0x03,  0x00, 0x00, 0x00, 0x08,  0x13, 0x3D, 0x17, 0x4F,  0x96, 0x08, 0x00, 0x07,
+  0x83, 0x00, 0x00, 0x00,  0x02, 0x08, 0x03, 0x1C,  0x96, 0x07, 0x00, 0x07,  0x03, 0x00, 0x00, 0x00,
+  0x08, 0x13, 0x3D, 0x17,  0x96, 0x8C, 0x00, 0x08,  0x14, 0x08, 0x15, 0x07,  0x12, 0x00, 0x00, 0x00,
+  0x08, 0x16, 0x07, 0x08,  0x00, 0x00, 0x00, 0x08,  0x17, 0x07, 0x14, 0x00,  0x00, 0x00, 0x08, 0x18,
+  0x07, 0x11, 0x00, 0x00,  0x00, 0x08, 0x19, 0x07,  0x2E, 0x00, 0x00, 0x00,  0x08, 0x1A, 0x07, 0x28,
+  0x00, 0x00, 0x00, 0x08,  0x1B, 0x07, 0x23, 0x00,  0x00, 0x00, 0x08, 0x1C,  0x07, 0x0D, 0x00, 0x00,
+  0x00, 0x08, 0x1D, 0x07,  0x1B, 0x00, 0x00, 0x00,  0x08, 0x1E, 0x07, 0x24,  0x00, 0x00, 0x00, 0x08,
+  0x1F, 0x07, 0x2D, 0x00,  0x00, 0x00, 0x08, 0x20,  0x07, 0x25, 0x00, 0x00,  0x00, 0x08, 0x21, 0x07,
+  0x22, 0x00, 0x00, 0x00,  0x08, 0x22, 0x07, 0x21,  0x00, 0x00, 0x00, 0x08,  0x23, 0x07, 0x27, 0x00,
+  0x00, 0x00, 0x08, 0x24,  0x07, 0x10, 0x00, 0x00,  0x00, 0x08, 0x25, 0x07,  0x20, 0x00, 0x00, 0x00,
+  0x08, 0x26, 0x07, 0x09,  0x00, 0x00, 0x00, 0x08,  0x27, 0x07, 0x26, 0x00,  0x00, 0x00, 0x07, 0x13,
+  0x00, 0x00, 0x00, 0x43,  0x1D, 0x96, 0x09, 0x00,  0x08, 0x28, 0x07, 0x20,  0x03, 0x00, 0x00, 0x08,
+  0x14, 0x1C, 0x96, 0x07,  0x00, 0x07, 0x03, 0x00,  0x00, 0x00, 0x08, 0x00,  0x3D, 0x17, 0x96, 0x02,
+  0x00, 0x08, 0x14, 0x1C,  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x03, 0x1C, 0x96,
+  0x02, 0x00, 0x08, 0x0F,  0x52, 0x17, 0x96, 0x08,  0x00, 0x07, 0x07, 0x00,  0x00, 0x00, 0x02, 0x08,
+  0x14, 0x1C, 0x96, 0x07,  0x00, 0x07, 0x03, 0x00,  0x00, 0x00, 0x08, 0x13,  0x3D, 0x17, 0x96, 0x09,
+  0x00, 0x08, 0x29, 0x07,  0x00, 0x00, 0x00, 0x00,  0x08, 0x2A, 0x40, 0x1D,  0x96, 0x02, 0x00, 0x08,
+  0x29, 0x1C, 0x96, 0x13,  0x00, 0x08, 0x2B, 0x07,  0x00, 0x00, 0x00, 0x00,  0x07, 0x05, 0x00, 0x00,
+  0x00, 0x07, 0x02, 0x00,  0x00, 0x00, 0x08, 0x01,  0x3D, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x29, 0x1C,
+  0x96, 0x13, 0x00, 0x08,  0x2C, 0x07, 0x01, 0x00,  0x00, 0x00, 0x07, 0x05,  0x00, 0x00, 0x00, 0x07,
+  0x02, 0x00, 0x00, 0x00,  0x08, 0x01, 0x3D, 0x4F,  0x96, 0x02, 0x00, 0x08,  0x29, 0x1C, 0x96, 0x07,
+  0x00, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x03,  0x1C, 0x96, 0x02, 0x00,  0x08, 0x0F, 0x52, 0x17,
+  0x96, 0x09, 0x00, 0x08,  0x2D, 0x07, 0x00, 0x00,  0x00, 0x00, 0x08, 0x2A,  0x40, 0x1D, 0x96, 0x02,
+  0x00, 0x08, 0x2D, 0x1C,  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x03, 0x1C, 0x96,
+  0x02, 0x00, 0x08, 0x0F,  0x52, 0x17, 0x96, 0x0E,  0x00, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x2E,
+  0x07, 0x9A, 0x02, 0x00,  0x00, 0x08, 0x2D, 0x1C,  0x96, 0x07, 0x00, 0x07,  0x04, 0x00, 0x00, 0x00,
+  0x08, 0x02, 0x3D, 0x17,  0x96, 0x02, 0x00, 0x08,  0x2F, 0x1C, 0x96, 0x02,  0x00, 0x08, 0x30, 0x4E,
+  0x96, 0x03, 0x00, 0x08,  0x31, 0x03, 0x4F, 0x96,  0x02, 0x00, 0x08, 0x2F,  0x1C, 0x96, 0x02, 0x00,
+  0x08, 0x30, 0x4E, 0x96,  0x03, 0x00, 0x08, 0x32,  0x03, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x2F, 0x1C,
+  0x96, 0x02, 0x00, 0x08,  0x30, 0x4E, 0x96, 0x03,  0x00, 0x08, 0x33, 0x03,  0x4F, 0x96, 0x02, 0x00,
+  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x04, 0x00,  0x08, 0x34, 0x08, 0x35,
+  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x13, 0x00,
+  0x08, 0x36, 0x07, 0x00,  0x00, 0x00, 0x00, 0x07,  0x2D, 0x01, 0x00, 0x00,  0x07, 0x02, 0x00, 0x00,
+  0x00, 0x08, 0x01, 0x3D,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,
+  0x4E, 0x96, 0x13, 0x00,  0x08, 0x37, 0x07, 0x03,  0x00, 0x00, 0x00, 0x07,  0x2D, 0x01, 0x00, 0x00,
+  0x07, 0x02, 0x00, 0x00,  0x00, 0x08, 0x01, 0x3D,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,
+  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x02, 0x00,  0x08, 0x38, 0x9B, 0x05,  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x4F, 0x96,  0x02, 0x00, 0x08, 0x2F,  0x1C, 0x96, 0x02, 0x00,  0x08, 0x30, 0x4E, 0x96,
+  0x02, 0x00, 0x08, 0x39,  0x9B, 0x09, 0x00, 0x00,  0x01, 0x00, 0x73, 0x72,  0x63, 0x00, 0x64, 0x00,
+  0x96, 0x02, 0x00, 0x08,  0x3A, 0x1C, 0x96, 0x01,  0x00, 0x02, 0x49, 0x12,  0x9D, 0x02, 0x00, 0x19,
+  0x00, 0x96, 0x09, 0x00,  0x05, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x08,  0x06, 0x1C, 0x96, 0x02,
+  0x00, 0x08, 0x38, 0x52,  0x17, 0x99, 0x02, 0x00,  0x3A, 0x00, 0x96, 0x02,  0x00, 0x08, 0x3A, 0x1C,
+  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x06, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x37,
+  0x52, 0x17, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x04, 0x00, 0x08,  0x31, 0x05, 0x01, 0x4F,
+  0x96, 0x09, 0x00, 0x05,  0x01, 0x07, 0x01, 0x00,  0x00, 0x00, 0x08, 0x06,  0x1C, 0x96, 0x02, 0x00,
+  0x08, 0x38, 0x52, 0x17,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,  0x02, 0x00, 0x08, 0x30,
+  0x4E, 0x96, 0x02, 0x00,  0x08, 0x3B, 0x9B, 0x05,  0x00, 0x00, 0x00, 0x00,  0xB3, 0x00, 0x96, 0x03,
+  0x00, 0x08, 0x3C, 0x02,  0x3C, 0x96, 0x02, 0x00,  0x08, 0x06, 0x46, 0x87,  0x01, 0x00, 0x00, 0x96,
+  0x01, 0x00, 0x02, 0x49,  0x9D, 0x02, 0x00, 0x91,  0x00, 0x96, 0x04, 0x00,  0x08, 0x07, 0x04, 0x00,
+  0x3C, 0x96, 0x02, 0x00,  0x08, 0x3C, 0x1C, 0x96,  0x01, 0x00, 0x02, 0x49,  0x9D, 0x02, 0x00, 0x41,
+  0x00, 0x96, 0x02, 0x00,  0x08, 0x3C, 0x4C, 0x1C,  0x96, 0x04, 0x00, 0x08,  0x3F, 0x08, 0x07, 0x1C,
+  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,  0x08, 0x3D, 0x3D, 0x47,  0x96, 0x02, 0x00, 0x08,
+  0x3E, 0x47, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x07, 0x1C, 0x4E, 0x96,
+  0x07, 0x00, 0x07, 0x01,  0x00, 0x00, 0x00, 0x08,  0x3D, 0x3D, 0x47, 0x47,  0x1D, 0x99, 0x02, 0x00,
+  0x33, 0x00, 0x96, 0x04,  0x00, 0x08, 0x3C, 0x08,  0x07, 0x1C, 0x96, 0x07,  0x00, 0x07, 0x01, 0x00,
+  0x00, 0x00, 0x08, 0x3D,  0x3D, 0x96, 0x02, 0x00,  0x08, 0x3E, 0x47, 0x96,  0x02, 0x00, 0x08, 0x06,
+  0x1C, 0x96, 0x02, 0x00,  0x08, 0x07, 0x1C, 0x4E,  0x96, 0x07, 0x00, 0x07,  0x01, 0x00, 0x00, 0x00,
+  0x08, 0x3D, 0x3D, 0x47,  0x1D, 0x99, 0x02, 0x00,  0x61, 0xFF, 0x96, 0x02,  0x00, 0x08, 0x3C, 0x1C,
+  0x3E, 0x4F, 0x96, 0x02,  0x00, 0x08, 0x2F, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x30, 0x4E, 0x96, 0x02,
+  0x00, 0x08, 0x40, 0x9B,  0x05, 0x00, 0x00, 0x00,  0x00, 0x0D, 0x00, 0x96,  0x02, 0x00, 0x08, 0x06,
+  0x1C, 0x96, 0x02, 0x00,  0x08, 0x32, 0x4E, 0x3E,  0x4F, 0x96, 0x02, 0x00,  0x08, 0x2F, 0x1C, 0x96,
+  0x02, 0x00, 0x08, 0x30,  0x4E, 0x96, 0x02, 0x00,  0x08, 0x41, 0x9B, 0x05,  0x00, 0x00, 0x00, 0x00,
+  0x0D, 0x00, 0x96, 0x02,  0x00, 0x08, 0x06, 0x1C,  0x96, 0x02, 0x00, 0x08,  0x33, 0x4E, 0x3E, 0x4F,
+  0x96, 0x08, 0x00, 0x07,  0x84, 0x00, 0x00, 0x00,  0x02, 0x08, 0x2F, 0x1C,  0x96, 0x02, 0x00, 0x08,
+  0x30, 0x4E, 0x96, 0x07,  0x00, 0x07, 0x03, 0x00,  0x00, 0x00, 0x08, 0x13,  0x3D, 0x17, 0x00
 };
 
diff --git a/libswfdec/swfdec_loadvars_as.c b/libswfdec/swfdec_loadvars_as.c
new file mode 100644
index 0000000..2e1553a
--- /dev/null
+++ b/libswfdec/swfdec_loadvars_as.c
@@ -0,0 +1,70 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *		 2007 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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 <string.h>
+
+#include "swfdec_debug.h"
+#include "swfdec_as_types.h"
+#include "swfdec_as_object.h"
+#include "swfdec_as_string.h"
+#include "swfdec_as_strings.h"
+#include "swfdec_player_internal.h"
+
+/*** AS CODE ***/
+
+SWFDEC_AS_NATIVE (301, 3, swfdec_loadvars_decode)
+void
+swfdec_loadvars_decode (SwfdecAsContext *cx, SwfdecAsObject *obj,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
+{
+  if (argc > 0) {
+    SwfdecAsValue val;
+    const char *str;
+    char **varlist, *p;
+    guint i;
+
+    str =
+      swfdec_as_string_unescape (cx, swfdec_as_value_to_string (cx, &argv[0]));
+    if (str == NULL)
+      return;
+
+    varlist = g_strsplit (str, "&", -1);
+
+    for (i = 0; varlist[i] != NULL; i++) {
+      p = strchr (varlist[i], '=');
+      if (p != NULL) {
+	*p++ = '\0';
+	if (*p == '\0')
+	  p = NULL;
+      }
+
+      if (p != NULL) {
+	SWFDEC_AS_VALUE_SET_STRING (&val, swfdec_as_context_get_string (cx, p));
+      } else {
+	SWFDEC_AS_VALUE_SET_STRING (&val, SWFDEC_AS_STR_EMPTY);
+      }
+      swfdec_as_object_set_variable (obj, swfdec_as_context_get_string (cx, varlist[i]), &val);
+    }
+  }
+}
diff-tree a7ae2ccc6a9f28b013e31293fcfa87b7c1b7fd88 (from 25c7f3ad0a28525a041bfe895f04aeeaf2c73375)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 11:15:47 2007 +0300

    Mark _bytesLoaded and _bytesTotal hidden in LoadObject

diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
index 6542f7c..2b19f07 100644
--- a/libswfdec/swfdec_load_object.c
+++ b/libswfdec/swfdec_load_object.c
@@ -45,12 +45,12 @@ swfdec_load_object_loader_target_parse (
   SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
 
   SWFDEC_AS_VALUE_SET_INT (&val, swfdec_loader_get_loaded (loader));
-  swfdec_as_object_set_variable (load_object->target,
-      SWFDEC_AS_STR__bytesLoaded, &val);
+  swfdec_as_object_set_variable_and_flags (load_object->target,
+      SWFDEC_AS_STR__bytesLoaded, &val, SWFDEC_AS_VARIABLE_HIDDEN);
 
   SWFDEC_AS_VALUE_SET_INT (&val, swfdec_loader_get_size (loader));
-  swfdec_as_object_set_variable (load_object->target, SWFDEC_AS_STR__bytesTotal,
-      &val);
+  swfdec_as_object_set_variable_and_flags (load_object->target,
+      SWFDEC_AS_STR__bytesTotal, &val, SWFDEC_AS_VARIABLE_HIDDEN);
 }
 
 static void
@@ -186,8 +186,8 @@ swfdec_load_object_load (SwfdecLoadObjec
   swfdec_loader_set_data_type (load_object->loader, SWFDEC_LOADER_DATA_TEXT);
 
   SWFDEC_AS_VALUE_SET_INT (&val, 0);
-  swfdec_as_object_set_variable (load_object->target,
-      SWFDEC_AS_STR__bytesLoaded, &val);
+  swfdec_as_object_set_variable_and_flags (load_object->target,
+      SWFDEC_AS_STR__bytesLoaded, &val, SWFDEC_AS_VARIABLE_HIDDEN);
 }
 
 SwfdecAsObject *
diff-tree 25c7f3ad0a28525a041bfe895f04aeeaf2c73375 (from c7b91a2f93c264e6c06adabe1b4fcd97fb590c50)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Mon Aug 20 11:14:30 2007 +0300

    Make a version of unescape function that is available from the code

diff --git a/libswfdec/swfdec_as_string.c b/libswfdec/swfdec_as_string.c
index 318a363..a200a22 100644
--- a/libswfdec/swfdec_as_string.c
+++ b/libswfdec/swfdec_as_string.c
@@ -465,12 +465,10 @@ swfdec_as_string_toUpperCase (SwfdecAsCo
 
 /* escape and unescape are implemented here so the mad string functions share the same place */
 
-static void
-swfdec_as_string_unescape_5 (SwfdecAsContext *cx, SwfdecAsObject *object,
-    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+static char *
+swfdec_as_string_unescape_5 (SwfdecAsContext *cx, const char *msg)
 {
   GByteArray *array;
-  const char *msg;
   char cur = 0; /* currently decoded character */
   char *out, *in, *s;
   guint decoding = 0; /* set if we're decoding a %XY string */
@@ -480,11 +478,10 @@ swfdec_as_string_unescape_5 (SwfdecAsCon
   g_byte_array_append (array, (guchar *) chr, 1); \
 }G_STMT_END
   array = g_byte_array_new ();
-  msg = swfdec_as_value_to_string (cx, &argv[0]);
   in = s = g_convert (msg, -1, "LATIN1", "UTF-8", NULL, NULL, NULL);
   if (s == NULL) {
     SWFDEC_FIXME ("%s can not be converted to utf8 - is this Flash 5 or what?", msg);
-    return;
+    return NULL;
   }
   while (*s != 0) {
     if (decoding) {
@@ -515,21 +512,19 @@ swfdec_as_string_unescape_5 (SwfdecAsCon
     s++;
   }
   g_free (in);
-  if (array->len == 0) {
-    SWFDEC_AS_VALUE_SET_UNDEFINED (ret);
-    return;
-  }
+  if (array->len == 0)
+    return NULL;
   cur = 0;
   g_byte_array_append (array, (guchar *) &cur, 1);
   out = g_convert ((char *) array->data, -1, "UTF-8", "LATIN1", NULL, NULL, NULL);
+  g_byte_array_free (array, TRUE);
   if (out) {
-    SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_get_string (cx, out));
-    g_free (out);
+    return out;
   } else {
     g_warning ("can't convert %s to UTF-8", msg);
-    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY);
+    g_free (out);
+    return NULL;
   }
-  g_byte_array_free (array, TRUE);
 #undef APPEND
 }
 
@@ -573,12 +568,11 @@ swfdec_as_string_escape (SwfdecAsContext
   g_free (in);
 }
 
-static void
-swfdec_as_string_unescape (SwfdecAsContext *cx, SwfdecAsObject *object,
-    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+static char *
+swfdec_as_string_unescape_6 (SwfdecAsContext *cx, const char *s)
 {
   GByteArray *array;
-  const char *s, *msg;
+  const char *msg;
   char cur = 0; /* currently decoded character */
   guint decoding = 0; /* set if we're decoding a %XY string */
   guint utf8left = 0; /* how many valid utf8 chars are still required */
@@ -615,7 +609,7 @@ swfdec_as_string_unescape (SwfdecAsConte
   } \
 }G_STMT_END
   array = g_byte_array_new ();
-  msg = s = swfdec_as_value_to_string (cx, &argv[0]);
+  msg = s;
   while (*s != 0) {
     if (decoding) {
       decoding++;
@@ -657,15 +651,42 @@ swfdec_as_string_unescape (SwfdecAsConte
   }
   g_byte_array_append (array, (guchar *) &cur, 1);
   if (g_utf8_validate ((char *) array->data, -1, NULL)) {
-    SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_get_string (cx, (char *) array->data));
+    return (char *) g_byte_array_free (array, FALSE);
   } else {
     g_warning ("%s unescaped is invalid UTF-8", msg);
-    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY);
+    g_byte_array_free (array, TRUE);
+    return NULL;
   }
-  g_byte_array_free (array, TRUE);
 #undef APPEND
 }
 
+char *
+swfdec_as_string_unescape (SwfdecAsContext *context, const char *string)
+{
+  if (context->version < 6) {
+    return swfdec_as_string_unescape_5 (context, string);
+  } else {
+    return swfdec_as_string_unescape_6 (context, string);
+  }
+}
+
+static void
+swfdec_as_string_unescape_internal (SwfdecAsContext *cx, SwfdecAsObject *object,
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
+{
+  char *result;
+
+  result =
+    swfdec_as_string_unescape (cx, swfdec_as_value_to_string (cx, &argv[0]));
+  if (result != NULL) {
+    SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_get_string (cx, result));
+  } else {
+    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_AS_STR_EMPTY);
+  }
+
+  g_free (result);
+}
+
 void
 swfdec_as_string_init_context (SwfdecAsContext *context, guint version)
 {
@@ -710,12 +731,7 @@ swfdec_as_string_init_context (SwfdecAsC
   }
 
   /* add properties to global object */
-  if (version <= 5) {
-    swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_escape, 0, swfdec_as_string_escape, 1);
-    swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_unescape, 0, swfdec_as_string_unescape_5, 1);
-  } else {
-    swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_escape, 0, swfdec_as_string_escape, 1);
-    swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_unescape, 0, swfdec_as_string_unescape, 1);
-  }
+  swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_escape, 0, swfdec_as_string_escape, 1);
+  swfdec_as_object_add_function (context->global, SWFDEC_AS_STR_unescape, 0, swfdec_as_string_unescape_internal, 1);
 }
 
diff --git a/libswfdec/swfdec_as_string.h b/libswfdec/swfdec_as_string.h
index 4266807..94d796e 100644
--- a/libswfdec/swfdec_as_string.h
+++ b/libswfdec/swfdec_as_string.h
@@ -49,6 +49,7 @@ GType		swfdec_as_string_get_type	(void);
 
 void		swfdec_as_string_init_context	(SwfdecAsContext *	context,
 						 guint			version);
+char		*swfdec_as_string_unescape	(SwfdecAsContext *	context,						 const char *		string);
 
 
 G_END_DECLS
diff-tree 409340bd1cd81d54715abb7d816f9f2e076432e9 (from c7b91a2f93c264e6c06adabe1b4fcd97fb590c50)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 11:40:47 2007 +0200

    check {} and [] don't call any constructors

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 800954c..91f6c63 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -230,6 +230,15 @@ EXTRA_DIST = \
 	comparisons-6.swf.trace \
 	comparisons-7.swf \
 	comparisons-7.swf.trace \
+	construct-constructors.as \
+	construct-constructors-5.swf \
+	construct-constructors-5.swf.trace \
+	construct-constructors-6.swf \
+	construct-constructors-6.swf.trace \
+	construct-constructors-7.swf \
+	construct-constructors-7.swf.trace \
+	construct-constructors-8.swf \
+	construct-constructors-8.swf.trace \
 	construct-properties.as \
 	construct-properties-5.swf \
 	construct-properties-5.swf.trace \
diff --git a/test/trace/construct-constructors-5.swf b/test/trace/construct-constructors-5.swf
new file mode 100644
index 0000000..9fb1cd1
Binary files /dev/null and b/test/trace/construct-constructors-5.swf differ
diff --git a/test/trace/construct-constructors-5.swf.trace b/test/trace/construct-constructors-5.swf.trace
new file mode 100644
index 0000000..3bc9e90
--- /dev/null
+++ b/test/trace/construct-constructors-5.swf.trace
@@ -0,0 +1,5 @@
+Check that [] and {} don't call their constructors
+new Array ()
+[]
+new Object ()
+{}
diff --git a/test/trace/construct-constructors-6.swf b/test/trace/construct-constructors-6.swf
new file mode 100644
index 0000000..e868a83
Binary files /dev/null and b/test/trace/construct-constructors-6.swf differ
diff --git a/test/trace/construct-constructors-6.swf.trace b/test/trace/construct-constructors-6.swf.trace
new file mode 100644
index 0000000..6f77d1d
--- /dev/null
+++ b/test/trace/construct-constructors-6.swf.trace
@@ -0,0 +1,7 @@
+Check that [] and {} don't call their constructors
+new Array ()
+  Array
+[]
+new Object ()
+  Object
+{}
diff --git a/test/trace/construct-constructors-7.swf b/test/trace/construct-constructors-7.swf
new file mode 100644
index 0000000..c9102a3
Binary files /dev/null and b/test/trace/construct-constructors-7.swf differ
diff --git a/test/trace/construct-constructors-7.swf.trace b/test/trace/construct-constructors-7.swf.trace
new file mode 100644
index 0000000..6f77d1d
--- /dev/null
+++ b/test/trace/construct-constructors-7.swf.trace
@@ -0,0 +1,7 @@
+Check that [] and {} don't call their constructors
+new Array ()
+  Array
+[]
+new Object ()
+  Object
+{}
diff --git a/test/trace/construct-constructors-8.swf b/test/trace/construct-constructors-8.swf
new file mode 100644
index 0000000..f795c9e
Binary files /dev/null and b/test/trace/construct-constructors-8.swf differ
diff --git a/test/trace/construct-constructors-8.swf.trace b/test/trace/construct-constructors-8.swf.trace
new file mode 100644
index 0000000..6f77d1d
--- /dev/null
+++ b/test/trace/construct-constructors-8.swf.trace
@@ -0,0 +1,7 @@
+Check that [] and {} don't call their constructors
+new Array ()
+  Array
+[]
+new Object ()
+  Object
+{}
diff --git a/test/trace/construct-constructors.as b/test/trace/construct-constructors.as
new file mode 100644
index 0000000..a71b1b9
--- /dev/null
+++ b/test/trace/construct-constructors.as
@@ -0,0 +1,20 @@
+// makeswf -v 7 -s 200x150 -r 1 -o construct-constructors.swf construct-constructors.as
+
+trace ("Check that [] and {} don't call their constructors");
+
+_global.Array = function () {
+  trace ("  Array");
+};
+_global.Object = function () {
+  trace ("  Object");
+};
+trace ("new Array ()");
+x = new Array ();
+trace ("[]");
+x = [];
+trace ("new Object ()");
+x = new Object ();
+trace ("{}");
+x = {};
+
+loadMovie ("FSCommand:quit", "");
diff-tree c7b91a2f93c264e6c06adabe1b4fcd97fb590c50 (from 919d9074df7d913998bc38edf3423f12eccdd4b8)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 11:01:19 2007 +0200

    add test for __constructor__ and constructor properties

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 3f7219f..800954c 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -230,6 +230,15 @@ EXTRA_DIST = \
 	comparisons-6.swf.trace \
 	comparisons-7.swf \
 	comparisons-7.swf.trace \
+	construct-properties.as \
+	construct-properties-5.swf \
+	construct-properties-5.swf.trace \
+	construct-properties-6.swf \
+	construct-properties-6.swf.trace \
+	construct-properties-7.swf \
+	construct-properties-7.swf.trace \
+	construct-properties-8.swf \
+	construct-properties-8.swf.trace \
 	constructor-prototype.swf \
 	constructor-prototype.swf.trace \
 	countdown.swf \
diff --git a/test/trace/construct-properties-5.swf b/test/trace/construct-properties-5.swf
new file mode 100644
index 0000000..2eff81e
Binary files /dev/null and b/test/trace/construct-properties-5.swf differ
diff --git a/test/trace/construct-properties-5.swf.trace b/test/trace/construct-properties-5.swf.trace
new file mode 100644
index 0000000..a4aaf4b
--- /dev/null
+++ b/test/trace/construct-properties-5.swf.trace
@@ -0,0 +1,93 @@
+Check initial properties of script-constructed objects
+>>> new Object ()
+[type Function]
+undefined
+undefined
+undefined
+[object Object]
+undefined
+>>> {}
+[type Function]
+undefined
+undefined
+undefined
+[object Object]
+undefined
+>>> []
+[type Function]
+undefined
+undefined
+undefined
+
+undefined
+>>> 
+[type Function]
+undefined
+undefined
+undefined
+[object Object]
+undefined
+>>> new Foo ()
+[type Function]
+undefined
+undefined
+undefined
+[object Object]
+undefined
+>>> 
+[type Function]
+undefined
+undefined
+undefined
+[object Object]
+undefined
+>>> new this.Foo ()
+[type Function]
+undefined
+undefined
+undefined
+[object Object]
+undefined
+undefined
+>>> 
+[type Function]
+undefined
+undefined
+undefined
+undefined
+undefined
+>>> new Foo () - without prototype
+[type Function]
+undefined
+undefined
+undefined
+undefined
+undefined
+>>> 
+[type Function]
+undefined
+undefined
+undefined
+undefined
+undefined
+>>> new this.Foo () - without prototype
+[type Function]
+undefined
+undefined
+undefined
+undefined
+undefined
+>>> 42
+[type Function]
+undefined
+undefined
+undefined
+[type Object]
+undefined
+>>> true
+[type Function]
+undefined
+undefined
+undefined
+[type Object]
+undefined
diff --git a/test/trace/construct-properties-6.swf b/test/trace/construct-properties-6.swf
new file mode 100644
index 0000000..f6cf779
Binary files /dev/null and b/test/trace/construct-properties-6.swf differ
diff --git a/test/trace/construct-properties-6.swf.trace b/test/trace/construct-properties-6.swf.trace
new file mode 100644
index 0000000..90d5425
--- /dev/null
+++ b/test/trace/construct-properties-6.swf.trace
@@ -0,0 +1,93 @@
+Check initial properties of script-constructed objects
+>>> new Object ()
+[type Function]
+true
+[type Function]
+true
+[object Object]
+true
+>>> {}
+[type Function]
+true
+undefined
+false
+[object Object]
+true
+>>> []
+[type Function]
+true
+undefined
+false
+
+true
+>>> 
+[type Function]
+true
+[type Function]
+true
+[object Object]
+true
+>>> new Foo ()
+[type Function]
+true
+[type Function]
+true
+[object Object]
+true
+>>> 
+[type Function]
+true
+[type Function]
+true
+[object Object]
+true
+>>> new this.Foo ()
+[type Function]
+true
+[type Function]
+true
+[object Object]
+true
+undefined
+>>> 
+[type Function]
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> new Foo () - without prototype
+[type Function]
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> 
+[type Function]
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> new this.Foo () - without prototype
+[type Function]
+true
+[type Function]
+true
+undefined
+false
+>>> 42
+[type Function]
+true
+[type Function]
+true
+[type Object]
+true
+>>> true
+[type Function]
+true
+[type Function]
+true
+[type Object]
+true
diff --git a/test/trace/construct-properties-7.swf b/test/trace/construct-properties-7.swf
new file mode 100644
index 0000000..263bfb1
Binary files /dev/null and b/test/trace/construct-properties-7.swf differ
diff --git a/test/trace/construct-properties-7.swf.trace b/test/trace/construct-properties-7.swf.trace
new file mode 100644
index 0000000..0063c74
--- /dev/null
+++ b/test/trace/construct-properties-7.swf.trace
@@ -0,0 +1,93 @@
+Check initial properties of script-constructed objects
+>>> new Object ()
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> {}
+[type Function]
+true
+undefined
+false
+[object Object]
+true
+>>> []
+[type Function]
+true
+undefined
+false
+
+true
+>>> 
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> new Foo ()
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> 
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> new this.Foo ()
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+undefined
+>>> 
+undefined
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> new Foo () - without prototype
+undefined
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> 
+undefined
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> new this.Foo () - without prototype
+undefined
+false
+[type Function]
+true
+undefined
+false
+>>> 42
+[type Function]
+false
+[type Function]
+true
+[type Object]
+true
+>>> true
+[type Function]
+false
+[type Function]
+true
+[type Object]
+true
diff --git a/test/trace/construct-properties-8.swf b/test/trace/construct-properties-8.swf
new file mode 100644
index 0000000..5f685c9
Binary files /dev/null and b/test/trace/construct-properties-8.swf differ
diff --git a/test/trace/construct-properties-8.swf.trace b/test/trace/construct-properties-8.swf.trace
new file mode 100644
index 0000000..0063c74
--- /dev/null
+++ b/test/trace/construct-properties-8.swf.trace
@@ -0,0 +1,93 @@
+Check initial properties of script-constructed objects
+>>> new Object ()
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> {}
+[type Function]
+true
+undefined
+false
+[object Object]
+true
+>>> []
+[type Function]
+true
+undefined
+false
+
+true
+>>> 
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> new Foo ()
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> 
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+>>> new this.Foo ()
+[type Function]
+false
+[type Function]
+true
+[object Object]
+true
+undefined
+>>> 
+undefined
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> new Foo () - without prototype
+undefined
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> 
+undefined
+undefined
+[type Function]
+undefined
+undefined
+undefined
+>>> new this.Foo () - without prototype
+undefined
+false
+[type Function]
+true
+undefined
+false
+>>> 42
+[type Function]
+false
+[type Function]
+true
+[type Object]
+true
+>>> true
+[type Function]
+false
+[type Function]
+true
+[type Object]
+true
diff --git a/test/trace/construct-properties.as b/test/trace/construct-properties.as
new file mode 100644
index 0000000..990952f
--- /dev/null
+++ b/test/trace/construct-properties.as
@@ -0,0 +1,36 @@
+// makeswf -v 7 -s 200x150 -r 1 -o construct-properties.swf construct-properties.as
+
+trace ("Check initial properties of script-constructed objects");
+
+function check (o, desc)
+{
+  trace (">>> " + desc);
+  trace (o.constructor);
+  trace (o.hasOwnProperty ("constructor"));
+  trace (o.__constructor__);
+  trace (o.hasOwnProperty ("__constructor__"));
+  trace (o.__proto__);
+  trace (o.hasOwnProperty ("__proto__"));
+};
+
+check (new Object (), "new Object ()");
+check ({}, "{}");
+check ([], "[]");
+Foo = function () {
+  check (this, "");
+};
+check (new Foo (), "new Foo ()");
+check (new this.Foo (), "new this.Foo ()");
+ASSetPropFlags (Foo, "prototype", 0, 7);
+delete Foo.prototype;
+trace (Foo.prototype);
+x = new Foo ();
+check (x, "new Foo () - without prototype");
+Foo.__proto__ = null;
+x = new Foo ();
+x.hasOwnProperty = Object.prototype.hasOwnProperty;
+check (x, "new this.Foo () - without prototype");
+check (42, "42");
+check (true, "true");
+
+loadMovie ("FSCommand:quit", "");
diff-tree 919d9074df7d913998bc38edf3423f12eccdd4b8 (from 4701b184371267c89a81413b410cae921df9027f)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 11:00:12 2007 +0200

    rework init code to set constructor and __constructor__ properties correctly

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 0bb7209..749b0d7 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -882,6 +882,7 @@ void
 swfdec_as_object_create (SwfdecAsFunction *fun, guint n_args, 
     const SwfdecAsValue *args)
 {
+  SwfdecAsValue val;
   SwfdecAsObject *new;
   SwfdecAsContext *context;
   SwfdecAsFunction *cur;
@@ -919,11 +920,27 @@ swfdec_as_object_create (SwfdecAsFunctio
     type = SWFDEC_TYPE_AS_OBJECT;
     size = sizeof (SwfdecAsObject);
   }
-  if (!swfdec_as_context_use_mem (context, size))
-    return;
-  new = g_object_new (type, NULL);
-  swfdec_as_object_add (new, context, size);
-  swfdec_as_object_set_constructor (new, SWFDEC_AS_OBJECT (fun));
+  if (swfdec_as_context_use_mem (context, size)) {
+    new = g_object_new (type, NULL);
+    swfdec_as_object_add (new, context, size);
+    /* set initial variables */
+    if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (fun), SWFDEC_AS_STR_prototype, &val)) {
+	swfdec_as_object_set_variable_and_flags (new, SWFDEC_AS_STR___proto__,
+	    &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
+    }
+    SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (fun));
+    if (context->version < 7) {
+      swfdec_as_object_set_variable_and_flags (new, SWFDEC_AS_STR_constructor, 
+	  &val, SWFDEC_AS_VARIABLE_HIDDEN);
+    }
+    if (context->version <= 5)
+      SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
+    swfdec_as_object_set_variable_and_flags (new, SWFDEC_AS_STR___constructor__, 
+	&val, SWFDEC_AS_VARIABLE_HIDDEN);
+  } else {
+    /* need to do this, since we must push something to the frame stack */
+    new = NULL;
+  }
   swfdec_as_function_call (fun, new, n_args, args, NULL);
   context->frame->construct = TRUE;
 }
@@ -937,7 +954,7 @@ swfdec_as_object_create (SwfdecAsFunctio
  * variables set automatically, but for objects you created yourself, you want
  * to call this function. This is essentially the same as the following script
  * code:
- * |[ object.__constructor__ = construct;
+ * |[ object.constructor = construct;
  * object.__proto__ = construct.prototype; ]|
  **/
 void
@@ -1083,6 +1100,8 @@ swfdec_as_object_init_context (SwfdecAsC
   }
   /* now, set our own */
   swfdec_as_object_set_variable (object, SWFDEC_AS_STR_prototype, &val);
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
+  swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
 
   if (version > 5) {
     swfdec_as_object_add_function (proto, SWFDEC_AS_STR_addProperty, 
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 0ddb8ff..243dabc 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -377,7 +377,7 @@ swfdec_movie_run_construct (SwfdecMovie 
   player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);
   g_queue_remove (player->construct_queue, movie);
   swfdec_movie_execute_script (movie, SWFDEC_EVENT_CONSTRUCT);
-  swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_STR___constructor__, 0, NULL, NULL);
+  swfdec_as_object_call (SWFDEC_AS_OBJECT (movie), SWFDEC_AS_STR_constructor, 0, NULL, NULL);
 }
 
 void
diff-tree 4701b184371267c89a81413b410cae921df9027f (from 3aa1d8b9d0bbf5897fdf678f845312476bb16a0d)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 10:59:19 2007 +0200

    functions in Flash > 5 print "[type Function]", too

diff --git a/libswfdec/swfdec_as_types.c b/libswfdec/swfdec_as_types.c
index 8d69fbb..11b11f2 100644
--- a/libswfdec/swfdec_as_types.c
+++ b/libswfdec/swfdec_as_types.c
@@ -31,6 +31,7 @@
 #include "swfdec_as_number.h"
 #include "swfdec_as_stack.h"
 #include "swfdec_as_strings.h"
+#include "swfdec_as_super.h"
 #include "swfdec_debug.h"
 #include "swfdec_movie.h"
 
@@ -378,7 +379,9 @@ swfdec_as_value_to_string (SwfdecAsConte
 	  swfdec_as_object_call (object, SWFDEC_AS_STR_toString, 0, NULL, &ret);
 	  if (SWFDEC_AS_VALUE_IS_STRING (&ret))
 	    return SWFDEC_AS_VALUE_GET_STRING (&ret);
-	  else if (context->version <= 5 && SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (value)))
+	  else if (SWFDEC_IS_AS_SUPER (SWFDEC_AS_VALUE_GET_OBJECT (value)))
+	    return SWFDEC_AS_STR__type_Object_;
+	  else if (SWFDEC_IS_AS_FUNCTION (SWFDEC_AS_VALUE_GET_OBJECT (value)))
 	    return SWFDEC_AS_STR__type_Function_;
 	  else
 	    return SWFDEC_AS_STR__type_Object_;
diff-tree 3aa1d8b9d0bbf5897fdf678f845312476bb16a0d (from 13378254ef972458c30937ac80dd8fb056358239)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 10:58:34 2007 +0200

    fix ActionExtends code
    
    It now creates an empty object and sets properties on it instead resetting
    properties on a default object

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 3b7c01f..72cf447 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1865,16 +1865,13 @@ swfdec_action_extends (SwfdecAsContext *
     goto fail;
   }
   super = SWFDEC_AS_VALUE_GET_OBJECT (superclass);
-  prototype = swfdec_as_object_new (cx);
+  prototype = swfdec_as_object_new_empty (cx);
   if (prototype == NULL)
     return;
   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_object_set_variable_flags (prototype, SWFDEC_AS_STR___constructor__,
-      SWFDEC_AS_VARIABLE_HIDDEN);
+  swfdec_as_object_set_variable_and_flags (prototype, SWFDEC_AS_STR___constructor__,
+      superclass, SWFDEC_AS_VARIABLE_HIDDEN);
   SWFDEC_AS_VALUE_SET_OBJECT (&proto, prototype);
   swfdec_as_object_set_variable (SWFDEC_AS_VALUE_GET_OBJECT (subclass),
       SWFDEC_AS_STR_prototype, &proto);
diff-tree 13378254ef972458c30937ac80dd8fb056358239 (from 1ce09b255198bdb2908cbc251e07bee76998e6a1)
Author: Benjamin Otte <otte at gnome.org>
Date:   Mon Aug 20 09:51:27 2007 +0200

    native objects have "constructor" set, not "__constructor__"

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index bfe02f5..0bb7209 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -961,7 +961,7 @@ swfdec_as_object_set_constructor (Swfdec
   swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___proto__, 
       &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, construct);
-  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___constructor__, 
+  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR_constructor, 
       &val, SWFDEC_AS_VARIABLE_HIDDEN);
 }
 
diff-tree 1ce09b255198bdb2908cbc251e07bee76998e6a1 (from 4e35fceb28469c2bc9ee49c9ec71573d6df8861e)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Aug 19 21:15:54 2007 +0200

    use set_variable_and_flags() instead of doing a seperate set_flags() calls

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 811be98..bfe02f5 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -775,8 +775,7 @@ swfdec_as_object_add_function (SwfdecAsO
   name = swfdec_as_context_get_string (object->context, name);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (function));
   /* FIXME: I'd like to make sure no such property exists yet */
-  swfdec_as_object_set_variable (object, name, &val);
-  swfdec_as_object_set_variable_flags (object, name, SWFDEC_AS_VARIABLE_HIDDEN);
+  swfdec_as_object_set_variable_and_flags (object, name, &val, SWFDEC_AS_VARIABLE_HIDDEN);
   return function;
 }
 
@@ -959,12 +958,11 @@ swfdec_as_object_set_constructor (Swfdec
     proto = object->context->Object_prototype;
   }
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
-  swfdec_as_object_set_variable (object, SWFDEC_AS_STR___proto__, &val);
-  swfdec_as_object_set_variable_flags (object, SWFDEC_AS_STR___proto__,
-      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
+  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___proto__, 
+      &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, construct);
-  swfdec_as_object_set_variable (object, SWFDEC_AS_STR___constructor__, &val);
-  swfdec_as_object_set_variable_flags (object, SWFDEC_AS_STR___constructor__, SWFDEC_AS_VARIABLE_HIDDEN);
+  swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR___constructor__, 
+      &val, SWFDEC_AS_VARIABLE_HIDDEN);
 }
 
 /**
diff-tree 4e35fceb28469c2bc9ee49c9ec71573d6df8861e (from cb77cc43c823c4f3260d6341cf5ed04b65783deb)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Aug 19 20:16:59 2007 +0200

    SwfdecAsObject->set() now takes a default_flags parameter
    
    This parameter is used to set the default set of flags, when a variable
    is newly created. Now we don't have the need to call set_flags() after
    every init function

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index a64b165..495bff1 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -332,7 +332,7 @@ swfdec_as_array_add (SwfdecAsObject *obj
 
 static void
 swfdec_as_array_set (SwfdecAsObject *object, const char *variable,
-    const SwfdecAsValue *val)
+    const SwfdecAsValue *val, guint flags)
 {
   char *end;
   gboolean indexvar = TRUE;
@@ -353,7 +353,7 @@ swfdec_as_array_set (SwfdecAsObject *obj
   }
 
   SWFDEC_AS_OBJECT_CLASS (swfdec_as_array_parent_class)->set (object, variable,
-      val);
+      val, flags);
 
   // if we added new value outside the current length, set a bigger length
   if (indexvar) {
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 2150244..811be98 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -157,7 +157,7 @@ swfdec_as_object_hash_lookup (SwfdecAsOb
 }
 
 static inline SwfdecAsVariable *
-swfdec_as_object_hash_create (SwfdecAsObject *object, const char *variable)
+swfdec_as_object_hash_create (SwfdecAsObject *object, const char *variable, guint flags)
 {
   SwfdecAsVariable *var;
 
@@ -166,6 +166,7 @@ swfdec_as_object_hash_create (SwfdecAsOb
   if (!swfdec_as_variable_name_is_valid (variable))
     return NULL;
   var = g_slice_new0 (SwfdecAsVariable);
+  var->flags = flags;
   g_hash_table_insert (object->properties, (gpointer) variable, var);
 
   return var;
@@ -194,20 +195,9 @@ swfdec_as_object_do_get (SwfdecAsObject 
   return TRUE;
 }
 
-static SwfdecAsVariable *
-swfdec_as_object_lookup_variable (SwfdecAsObject *object, const char *variable)
-{
-  SwfdecAsVariable *var;
-
-  var = swfdec_as_object_hash_lookup (object, variable);
-  if (var == NULL) 
-    var = swfdec_as_object_hash_create (object, variable);
-  return var;
-}
-
 static void
 swfdec_as_object_do_set (SwfdecAsObject *object, const char *variable, 
-    const SwfdecAsValue *val)
+    const SwfdecAsValue *val, guint flags)
 {
   SwfdecAsVariable *var;
 
@@ -241,7 +231,7 @@ swfdec_as_object_do_set (SwfdecAsObject 
     }
   }
   if (var == NULL) {
-    var = swfdec_as_object_hash_create (object, variable);
+    var = swfdec_as_object_hash_create (object, variable, flags);
     if (var == NULL)
       return;
   }
@@ -549,12 +539,25 @@ swfdec_as_object_collect (SwfdecAsObject
  * @value: value to set the variable to
  *
  * Sets a variable on @object. It is not guaranteed that getting the variable
- * after setting it results in the same value, as some variables can be 
- * read-only or require a specific type.
+ * after setting it results in the same value. This is a mcaro that calls 
+ * swfdec_as_object_set_variable_and_flags()
+ **/
+/**
+ * swfdec_as_object_set_variable:
+ * @object: a #SwfdecAsObject
+ * @variable: garbage-collected name of the variable to set
+ * @value: value to set the variable to
+ * @default_flags: flags to use if creating the variable anew - the flags will
+ *                 be ignored if the property already exists.
+ *
+ * Sets a variable on @object. It is not guaranteed that getting the variable
+ * after setting it results in the same value, because various mechanisms (like
+ * the Actionscript Object.addProperty function or constant variables) can 
+ * avoid this.
  **/
 void
-swfdec_as_object_set_variable (SwfdecAsObject *object,
-    const char *variable, const SwfdecAsValue *value)
+swfdec_as_object_set_variable_and_flags (SwfdecAsObject *object,
+    const char *variable, const SwfdecAsValue *value, guint default_flags)
 {
   SwfdecAsObjectClass *klass;
 
@@ -563,7 +566,7 @@ swfdec_as_object_set_variable (SwfdecAsO
   g_return_if_fail (SWFDEC_IS_AS_VALUE (value));
 
   klass = SWFDEC_AS_OBJECT_GET_CLASS (object);
-  klass->set (object, variable, value);
+  klass->set (object, variable, value, default_flags);
 }
 
 /**
@@ -987,12 +990,13 @@ swfdec_as_object_add_variable (SwfdecAsO
   g_return_if_fail (SWFDEC_IS_AS_FUNCTION (get));
   g_return_if_fail (set == NULL || SWFDEC_IS_AS_FUNCTION (set));
 
-  var = swfdec_as_object_lookup_variable (object, variable);
+  var = swfdec_as_object_hash_lookup (object, variable);
+  if (var == NULL) 
+    var = swfdec_as_object_hash_create (object, variable, 0);
   if (var == NULL)
     return;
   var->get = get;
   var->set = set;
-  var->flags = 0;
   if (set == NULL)
     var->flags |= SWFDEC_AS_VARIABLE_CONSTANT;
 }
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 5baec7d..1109110 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -72,7 +72,8 @@ struct _SwfdecAsObjectClass {
   /* set the variable - and return it (or NULL on error) */
   void			(* set)			(SwfdecAsObject *	object,
 						 const char *		variable,
-						 const SwfdecAsValue *	val);
+						 const SwfdecAsValue *	val,
+						 guint			default_flags);
   /* set flags of a variable */
   void			(* set_flags)	      	(SwfdecAsObject *	object,
 						 const char *		variable,
@@ -109,9 +110,13 @@ void		swfdec_as_object_add		(SwfdecAsObj
 
 /* I'd like to name these [gs]et_property, but binding authors will complain
  * about overlap with g_object_[gs]et_property then */
-void		swfdec_as_object_set_variable	(SwfdecAsObject *	object,
+#define swfdec_as_object_set_variable(object, variable, value) \
+  swfdec_as_object_set_variable_and_flags (object, variable, value, 0)
+void		swfdec_as_object_set_variable_and_flags
+						(SwfdecAsObject *	object,
 						 const char *		variable,
-						 const SwfdecAsValue *	value);
+						 const SwfdecAsValue *	value,
+						 guint			default_flags);
 void		swfdec_as_object_add_variable	(SwfdecAsObject *	object,
 						 const char *		variable, 
 						 SwfdecAsFunction *	get,
diff --git a/libswfdec/swfdec_as_super.c b/libswfdec/swfdec_as_super.c
index 653c30a..aa75a0b 100644
--- a/libswfdec/swfdec_as_super.c
+++ b/libswfdec/swfdec_as_super.c
@@ -88,7 +88,7 @@ swfdec_as_super_get (SwfdecAsObject *obj
 }
 
 static void
-swfdec_as_super_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val)
+swfdec_as_super_set (SwfdecAsObject *object, const char *variable, const SwfdecAsValue *val, guint flags)
 {
   /* This seems to be ignored completely */
 }
diff --git a/libswfdec/swfdec_as_with.c b/libswfdec/swfdec_as_with.c
index 62af9b8..a6b032e 100644
--- a/libswfdec/swfdec_as_with.c
+++ b/libswfdec/swfdec_as_with.c
@@ -60,12 +60,12 @@ swfdec_as_with_get (SwfdecAsObject *obje
 
 static void
 swfdec_as_with_set (SwfdecAsObject *object, const char *variable,
-    const SwfdecAsValue *val)
+    const SwfdecAsValue *val, guint flags)
 {
   SwfdecAsWith *with = SWFDEC_AS_WITH (object);
   SwfdecAsObjectClass *klass = SWFDEC_AS_OBJECT_GET_CLASS (with->object);
 
-  klass->set (with->object, variable, val);
+  klass->set (with->object, variable, val, flags);
 }
 
 static void
diff --git a/libswfdec/swfdec_movie.c b/libswfdec/swfdec_movie.c
index 3bac79f..0ddb8ff 100644
--- a/libswfdec/swfdec_movie.c
+++ b/libswfdec/swfdec_movie.c
@@ -875,7 +875,7 @@ swfdec_movie_get_variable (SwfdecAsObjec
 
 static void
 swfdec_movie_set_variable (SwfdecAsObject *object, const char *variable, 
-    const SwfdecAsValue *val)
+    const SwfdecAsValue *val, guint flags)
 {
   SwfdecMovie *movie = SWFDEC_MOVIE (object);
 
@@ -883,7 +883,7 @@ swfdec_movie_set_variable (SwfdecAsObjec
     return;
   if (swfdec_movie_set_asprop (movie, variable, val))
     return;
-  SWFDEC_AS_OBJECT_CLASS (swfdec_movie_parent_class)->set (object, variable, val);
+  SWFDEC_AS_OBJECT_CLASS (swfdec_movie_parent_class)->set (object, variable, val, flags);
 }
 
 static char *
diff-tree cb77cc43c823c4f3260d6341cf5ed04b65783deb (from 5d29f9261756c094b4d0f9a80da05fb6892094bf)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Aug 19 20:01:22 2007 +0200

    remove the third argument from swfdec_as_object_set_constructor()
    
    It was FALSE every time

diff --git a/libswfdec/swfdec_as_array.c b/libswfdec/swfdec_as_array.c
index 9d245c3..a64b165 100644
--- a/libswfdec/swfdec_as_array.c
+++ b/libswfdec/swfdec_as_array.c
@@ -400,7 +400,7 @@ swfdec_as_array_new (SwfdecAsContext *co
     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);
+  swfdec_as_object_set_constructor (ret, context->Array);
   return ret;
 }
 
@@ -1052,8 +1052,7 @@ swfdec_as_array_construct (SwfdecAsConte
     swfdec_as_object_add (object, cx, sizeof (SwfdecAsArray));
     swfdec_as_object_get_variable (cx->global, SWFDEC_AS_STR_Array, &val);
     if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
-      swfdec_as_object_set_constructor (object,
-	  SWFDEC_AS_VALUE_GET_OBJECT (&val), FALSE);
+      swfdec_as_object_set_constructor (object, SWFDEC_AS_VALUE_GET_OBJECT (&val));
     } else {
       SWFDEC_INFO ("\"Array\" is not an object");
     }
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 8d4df41..2150244 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -921,7 +921,7 @@ swfdec_as_object_create (SwfdecAsFunctio
     return;
   new = g_object_new (type, NULL);
   swfdec_as_object_add (new, context, size);
-  swfdec_as_object_set_constructor (new, SWFDEC_AS_OBJECT (fun), FALSE);
+  swfdec_as_object_set_constructor (new, SWFDEC_AS_OBJECT (fun));
   swfdec_as_function_call (fun, new, n_args, args, NULL);
   context->frame->construct = TRUE;
 }
@@ -930,9 +930,6 @@ swfdec_as_object_create (SwfdecAsFunctio
  * swfdec_as_object_set_constructor:
  * @object: a #SwfdecAsObject
  * @construct: the constructor of @object
- * @scripted: %TRUE if this object was created by a script. Flash sets the 
- *            property named "__constructor__" on script-created objects, but
- *            "constructor" on native ones.
  *
  * Sets the constructor variables for @object. Most objects get these 
  * variables set automatically, but for objects you created yourself, you want
@@ -942,8 +939,7 @@ swfdec_as_object_create (SwfdecAsFunctio
  * object.__proto__ = construct.prototype; ]|
  **/
 void
-swfdec_as_object_set_constructor (SwfdecAsObject *object,
-    SwfdecAsObject *construct, gboolean scripted)
+swfdec_as_object_set_constructor (SwfdecAsObject *object, SwfdecAsObject *construct)
 {
   SwfdecAsValue val;
   SwfdecAsObject *proto;
@@ -964,12 +960,8 @@ swfdec_as_object_set_constructor (Swfdec
   swfdec_as_object_set_variable_flags (object, SWFDEC_AS_STR___proto__,
       SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, construct);
-  swfdec_as_object_set_variable (object,
-      scripted ? SWFDEC_AS_STR_constructor : SWFDEC_AS_STR___constructor__,
-      &val);
-  swfdec_as_object_set_variable_flags (object,
-      scripted ? SWFDEC_AS_STR_constructor : SWFDEC_AS_STR___constructor__,
-      SWFDEC_AS_VARIABLE_HIDDEN);
+  swfdec_as_object_set_variable (object, SWFDEC_AS_STR___constructor__, &val);
+  swfdec_as_object_set_variable_flags (object, SWFDEC_AS_STR___constructor__, SWFDEC_AS_VARIABLE_HIDDEN);
 }
 
 /**
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 55bfc05..5baec7d 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -99,8 +99,7 @@ void		swfdec_as_object_create		(SwfdecAs
 						 guint			n_args,
 						 const SwfdecAsValue *	args);
 void		swfdec_as_object_set_constructor(SwfdecAsObject *	object,
-						 SwfdecAsObject *	construct,
-						 gboolean		scripted);
+						 SwfdecAsObject *	construct);
 SwfdecAsObject *swfdec_as_object_resolve	(SwfdecAsObject *	object);
 char *		swfdec_as_object_get_debug	(SwfdecAsObject *	object);
 
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 39a1cb1..942dadf 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -1444,7 +1444,7 @@ swfdec_player_initialize (SwfdecPlayer *
     }
     if (context->state == SWFDEC_AS_CONTEXT_NEW) {
       context->state = SWFDEC_AS_CONTEXT_RUNNING;
-      swfdec_as_object_set_constructor (player->roots->data, player->MovieClip, FALSE);
+      swfdec_as_object_set_constructor (player->roots->data, player->MovieClip);
     }
   }
   SWFDEC_INFO ("initializing player to size %ux%u", width, height);
diff --git a/libswfdec/swfdec_sprite_movie.c b/libswfdec/swfdec_sprite_movie.c
index 4f9067d..9af9370 100644
--- a/libswfdec/swfdec_sprite_movie.c
+++ b/libswfdec/swfdec_sprite_movie.c
@@ -583,7 +583,7 @@ swfdec_sprite_movie_init_movie (SwfdecMo
   if (constructor == NULL)
     constructor = SWFDEC_PLAYER (context)->MovieClip;
 
-  swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), constructor, FALSE);
+  swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), constructor);
   swfdec_sprite_movie_goto (movie, 1);
   if (!swfdec_sprite_movie_iterate_end (mov)) {
     g_assert_not_reached ();
diff --git a/libswfdec/swfdec_video_movie.c b/libswfdec/swfdec_video_movie.c
index 60676e0..eeb137c 100644
--- a/libswfdec/swfdec_video_movie.c
+++ b/libswfdec/swfdec_video_movie.c
@@ -100,7 +100,7 @@ swfdec_video_movie_init_movie (SwfdecMov
 {
   SwfdecPlayer *player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (movie)->context);
 
-  swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), player->Video, FALSE);
+  swfdec_as_object_set_constructor (SWFDEC_AS_OBJECT (movie), player->Video);
 }
 
 static void
diff-tree 5d29f9261756c094b4d0f9a80da05fb6892094bf (from 58fb9a2cd750b3fb08db924a7c2e52d38b766630)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Aug 19 17:53:43 2007 +0200

    disconnect signal handlers before dispose
    
    Also make the finished function a signal handler, so we can disconnect it

diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c
index 65897bc..c98f029 100644
--- a/libswfdec-gtk/swfdec_gtk_loader.c
+++ b/libswfdec-gtk/swfdec_gtk_loader.c
@@ -68,19 +68,6 @@ struct _SwfdecGtkLoaderClass {
 G_DEFINE_TYPE (SwfdecGtkLoader, swfdec_gtk_loader, SWFDEC_TYPE_FILE_LOADER)
 
 static void
-swfdec_gtk_loader_dispose (GObject *object)
-{
-  SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (object);
-
-  if (gtk->message) {
-    g_object_unref (gtk->message);
-    gtk->message = NULL;
-  }
-
-  G_OBJECT_CLASS (swfdec_gtk_loader_parent_class)->dispose (object);
-}
-
-static void
 swfdec_gtk_loader_ensure_open (SwfdecGtkLoader *gtk)
 {
   char *real_uri;
@@ -123,7 +110,7 @@ swfdec_gtk_loader_headers (SoupMessage *
 }
 
 static void
-swfdec_gtk_loader_finish (SoupMessage *msg, gpointer loader)
+swfdec_gtk_loader_finished (SoupMessage *msg, gpointer loader)
 {
   if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
     swfdec_gtk_loader_ensure_open (loader);
@@ -136,6 +123,22 @@ swfdec_gtk_loader_finish (SoupMessage *m
 }
 
 static void
+swfdec_gtk_loader_dispose (GObject *object)
+{
+  SwfdecGtkLoader *gtk = SWFDEC_GTK_LOADER (object);
+
+  if (gtk->message) {
+    g_signal_handlers_disconnect_by_func (gtk->message, swfdec_gtk_loader_push, gtk);
+    g_signal_handlers_disconnect_by_func (gtk->message, swfdec_gtk_loader_headers, gtk);
+    g_signal_handlers_disconnect_by_func (gtk->message, swfdec_gtk_loader_finished, gtk);
+    g_object_unref (gtk->message);
+    gtk->message = NULL;
+  }
+
+  G_OBJECT_CLASS (swfdec_gtk_loader_parent_class)->dispose (object);
+}
+
+static void
 swfdec_gtk_loader_load (SwfdecLoader *loader, SwfdecLoader *parent,
     SwfdecLoaderRequest request, const char *data, gsize data_len)
 {
@@ -153,11 +156,12 @@ swfdec_gtk_loader_load (SwfdecLoader *lo
     soup_message_set_flags (gtk->message, SOUP_MESSAGE_OVERWRITE_CHUNKS);
     g_signal_connect (gtk->message, "got-chunk", G_CALLBACK (swfdec_gtk_loader_push), gtk);
     g_signal_connect (gtk->message, "got-headers", G_CALLBACK (swfdec_gtk_loader_headers), gtk);
+    g_signal_connect (gtk->message, "finished", G_CALLBACK (swfdec_gtk_loader_finished), gtk);
     if (data)
       soup_message_set_request (gtk->message, "appliation/x-www-urlencoded",
 	  SOUP_BUFFER_USER_OWNED, (char *) data, data_len);
     g_object_ref (gtk->message);
-    soup_session_queue_message (klass->session, gtk->message, swfdec_gtk_loader_finish, gtk);
+    soup_session_queue_message (klass->session, gtk->message, NULL, NULL);
   }
 }
 
diff-tree 58fb9a2cd750b3fb08db924a7c2e52d38b766630 (from c46107bbab094d82091c60aa7abb04c61eb17140)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Aug 19 17:34:37 2007 +0200

    implement swfdec_loader_set_size() by reading Content-Length header

diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c
index 415d418..65897bc 100644
--- a/libswfdec-gtk/swfdec_gtk_loader.c
+++ b/libswfdec-gtk/swfdec_gtk_loader.c
@@ -22,6 +22,8 @@
 #endif
 
 #include <libsoup/soup.h>
+#include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 #include "swfdec_gtk_loader.h"
 
@@ -105,6 +107,22 @@ swfdec_gtk_loader_push (SoupMessage *msg
 }
 
 static void
+swfdec_gtk_loader_headers (SoupMessage *msg, gpointer loader)
+{
+  const char *s = soup_message_get_header (msg->response_headers, "Content-Length");
+  unsigned long l;
+  char *end;
+
+  if (s == NULL)
+    return;
+
+  errno = 0;
+  l = strtoul (s, &end, 10);
+  if (errno == 0 && *end == 0)
+    swfdec_loader_set_size (loader, l);
+}
+
+static void
 swfdec_gtk_loader_finish (SoupMessage *msg, gpointer loader)
 {
   if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
@@ -134,6 +152,7 @@ swfdec_gtk_loader_load (SwfdecLoader *lo
 	swfdec_url_get_url (url));
     soup_message_set_flags (gtk->message, SOUP_MESSAGE_OVERWRITE_CHUNKS);
     g_signal_connect (gtk->message, "got-chunk", G_CALLBACK (swfdec_gtk_loader_push), gtk);
+    g_signal_connect (gtk->message, "got-headers", G_CALLBACK (swfdec_gtk_loader_headers), gtk);
     if (data)
       soup_message_set_request (gtk->message, "appliation/x-www-urlencoded",
 	  SOUP_BUFFER_USER_OWNED, (char *) data, data_len);
diff-tree c46107bbab094d82091c60aa7abb04c61eb17140 (from 5307f431c31026bf25f1abe9e642bb26256b3a5a)
Author: Benjamin Otte <otte at gnome.org>
Date:   Sun Aug 19 16:58:45 2007 +0200

    print a useful error message

diff --git a/libswfdec-gtk/swfdec_gtk_loader.c b/libswfdec-gtk/swfdec_gtk_loader.c
index aff6da1..415d418 100644
--- a/libswfdec-gtk/swfdec_gtk_loader.c
+++ b/libswfdec-gtk/swfdec_gtk_loader.c
@@ -111,7 +111,9 @@ swfdec_gtk_loader_finish (SoupMessage *m
     swfdec_gtk_loader_ensure_open (loader);
     swfdec_loader_eof (loader);
   } else {
-    swfdec_loader_error (loader, "FIXME: make useful error message");
+    char *s = g_strdup_printf ("%u %s", msg->status_code, msg->reason_phrase);
+    swfdec_loader_error (loader, s);
+    g_free (s);
   }
 }
 
diff-tree 5307f431c31026bf25f1abe9e642bb26256b3a5a (from 036bc27bbf78889a7bea8f8a3288457e46848cec)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 15:25:04 2007 +0300

    Add test case loadobject for the load method

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 794e7f1..3f7219f 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -478,6 +478,13 @@ EXTRA_DIST = \
 	load-4.swf.trace \
 	load-5.swf \
 	load-5.swf.trace \
+	loadobject.as \
+	loadobject-5.swf \
+	loadobject-5.swf.trace \
+	loadobject-6.swf \
+	loadobject-6.swf.trace \
+	loadobject-7.swf \
+	loadobject-7.swf.trace \
 	local.swf \
 	local.swf.trace \
 	lots-of-arguments.as \
diff --git a/test/trace/loadobject-5.swf b/test/trace/loadobject-5.swf
new file mode 100644
index 0000000..b3b144d
Binary files /dev/null and b/test/trace/loadobject-5.swf differ
diff --git a/test/trace/loadobject-5.swf.trace b/test/trace/loadobject-5.swf.trace
new file mode 100644
index 0000000..ba49d21
--- /dev/null
+++ b/test/trace/loadobject-5.swf.trace
@@ -0,0 +1,46 @@
+Loaded: 
+Total: 
+false
+Loaded: 
+Total: 
+true
+Loaded: 0
+Total: 
+true
+Loaded: 0
+Total: 
+Got: string '// makeswf -v 7 -r 1 -o loadobject-7.swf loadobject.as
+
+var obj = new Object ();
+
+obj.load = ASnative (301, 0);
+
+obj.onData = function (str) {
+  trace ("Got: " + typeof (str) + " '" + str + "'");
+  trace ("Loaded: " + this._bytesLoaded);
+  trace ("Total: " + this._bytesTotal);
+};
+
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ());
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("loadobject.as"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("404"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+
+function quit () {
+  loadMovie ("FSCommand:quit", "");
+};
+
+setInterval (quit, 1000);
+'
+Loaded: 755
+Total: 755
+Got: undefined ''
+Loaded: 755
+Total: 755
diff --git a/test/trace/loadobject-6.swf b/test/trace/loadobject-6.swf
new file mode 100644
index 0000000..3a19ff4
Binary files /dev/null and b/test/trace/loadobject-6.swf differ
diff --git a/test/trace/loadobject-6.swf.trace b/test/trace/loadobject-6.swf.trace
new file mode 100644
index 0000000..ba49d21
--- /dev/null
+++ b/test/trace/loadobject-6.swf.trace
@@ -0,0 +1,46 @@
+Loaded: 
+Total: 
+false
+Loaded: 
+Total: 
+true
+Loaded: 0
+Total: 
+true
+Loaded: 0
+Total: 
+Got: string '// makeswf -v 7 -r 1 -o loadobject-7.swf loadobject.as
+
+var obj = new Object ();
+
+obj.load = ASnative (301, 0);
+
+obj.onData = function (str) {
+  trace ("Got: " + typeof (str) + " '" + str + "'");
+  trace ("Loaded: " + this._bytesLoaded);
+  trace ("Total: " + this._bytesTotal);
+};
+
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ());
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("loadobject.as"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("404"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+
+function quit () {
+  loadMovie ("FSCommand:quit", "");
+};
+
+setInterval (quit, 1000);
+'
+Loaded: 755
+Total: 755
+Got: undefined ''
+Loaded: 755
+Total: 755
diff --git a/test/trace/loadobject-7.swf b/test/trace/loadobject-7.swf
new file mode 100644
index 0000000..4d580e6
Binary files /dev/null and b/test/trace/loadobject-7.swf differ
diff --git a/test/trace/loadobject-7.swf.trace b/test/trace/loadobject-7.swf.trace
new file mode 100644
index 0000000..8e6d8c0
--- /dev/null
+++ b/test/trace/loadobject-7.swf.trace
@@ -0,0 +1,46 @@
+Loaded: undefined
+Total: undefined
+false
+Loaded: undefined
+Total: undefined
+true
+Loaded: 0
+Total: undefined
+true
+Loaded: 0
+Total: undefined
+Got: string '// makeswf -v 7 -r 1 -o loadobject-7.swf loadobject.as
+
+var obj = new Object ();
+
+obj.load = ASnative (301, 0);
+
+obj.onData = function (str) {
+  trace ("Got: " + typeof (str) + " '" + str + "'");
+  trace ("Loaded: " + this._bytesLoaded);
+  trace ("Total: " + this._bytesTotal);
+};
+
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ());
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("loadobject.as"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("404"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+
+function quit () {
+  loadMovie ("FSCommand:quit", "");
+};
+
+setInterval (quit, 1000);
+'
+Loaded: 755
+Total: 755
+Got: undefined 'undefined'
+Loaded: 755
+Total: 755
diff --git a/test/trace/loadobject.as b/test/trace/loadobject.as
new file mode 100644
index 0000000..127e063
--- /dev/null
+++ b/test/trace/loadobject.as
@@ -0,0 +1,29 @@
+// makeswf -v 7 -r 1 -o loadobject-7.swf loadobject.as
+
+var obj = new Object ();
+
+obj.load = ASnative (301, 0);
+
+obj.onData = function (str) {
+  trace ("Got: " + typeof (str) + " '" + str + "'");
+  trace ("Loaded: " + this._bytesLoaded);
+  trace ("Total: " + this._bytesTotal);
+};
+
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ());
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("loadobject.as"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+trace (obj.load ("404"));
+trace ("Loaded: " + obj._bytesLoaded);
+trace ("Total: " + obj._bytesTotal);
+
+function quit () {
+  loadMovie ("FSCommand:quit", "");
+};
+
+setInterval (quit, 1000);
diff-tree 036bc27bbf78889a7bea8f8a3288457e46848cec (from c2e81f0fcd0fda22a358e9884a539e55d03510e5)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 14:33:06 2007 +0300

    Don't use program's output as format string in trace.c

diff --git a/test/trace/trace.c b/test/trace/trace.c
index 0f986e5..9725a0b 100644
--- a/test/trace/trace.c
+++ b/test/trace/trace.c
@@ -248,7 +248,7 @@ main (int argc, char **argv)
       Test *test = walk->data;
       
       run_test (test, NULL);
-      g_print (test->output);
+      g_print ("%s", test->output);
       if (!test->success) {
 	failures++;
 	g_string_append_printf (failed_tests, 
diff-tree c2e81f0fcd0fda22a358e9884a539e55d03510e5 (from 1e15b5e20599d5193ba0745cf1e11fac076e66f6)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 14:21:22 2007 +0300

    Allow calling XML.load with 0 params to return FALSE

diff --git a/libswfdec/swfdec_xml_as.c b/libswfdec/swfdec_xml_as.c
index 10f9d13..db31bc0 100644
--- a/libswfdec/swfdec_xml_as.c
+++ b/libswfdec/swfdec_xml_as.c
@@ -65,6 +65,6 @@ swfdec_xml_init_context (SwfdecPlayer *p
   SWFDEC_AS_VALUE_SET_OBJECT (&val, xml);
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_load, SWFDEC_TYPE_XML,
-      swfdec_load_object_load, 1);
+      swfdec_load_object_load, 0);
 }
 
diff-tree 1e15b5e20599d5193ba0745cf1e11fac076e66f6 (from d0bd628cea984172d9dfb185b9fbeba64348ed81)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 14:12:48 2007 +0300

    Fix load method crash when called without params and fix it's return values

diff --git a/libswfdec/swfdec_load_object_as.c b/libswfdec/swfdec_load_object_as.c
index e4ab4de..9df8c9f 100644
--- a/libswfdec/swfdec_load_object_as.c
+++ b/libswfdec/swfdec_load_object_as.c
@@ -36,6 +36,13 @@ swfdec_load_object_load (SwfdecAsContext
 {
   const char *url;
 
+  if (argc < 1) {
+    SWFDEC_AS_VALUE_SET_BOOLEAN (rval, FALSE);
+    return;
+  }
+
   url = swfdec_as_value_to_string (cx, &argv[0]);
   swfdec_load_object_new (obj, url);
+
+  SWFDEC_AS_VALUE_SET_BOOLEAN (rval, TRUE);
 }
diff-tree d0bd628cea984172d9dfb185b9fbeba64348ed81 (from e068c79c89238e20d94e93992489aef7a078fada)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 14:08:43 2007 +0300

    Reformat LoadObject code a little

diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
index ae017e2..6542f7c 100644
--- a/libswfdec/swfdec_load_object.c
+++ b/libswfdec/swfdec_load_object.c
@@ -42,13 +42,15 @@ swfdec_load_object_loader_target_parse (
     SwfdecLoader *loader)
 {
   SwfdecAsValue val;
-  SwfdecAsObject *object = SWFDEC_LOAD_OBJECT (target)->target;
+  SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
 
   SWFDEC_AS_VALUE_SET_INT (&val, swfdec_loader_get_loaded (loader));
-  swfdec_as_object_set_variable (object, SWFDEC_AS_STR__bytesLoaded, &val);
+  swfdec_as_object_set_variable (load_object->target,
+      SWFDEC_AS_STR__bytesLoaded, &val);
 
   SWFDEC_AS_VALUE_SET_INT (&val, swfdec_loader_get_size (loader));
-  swfdec_as_object_set_variable (object, SWFDEC_AS_STR__bytesTotal, &val);
+  swfdec_as_object_set_variable (load_object->target, SWFDEC_AS_STR__bytesTotal,
+      &val);
 }
 
 static void
@@ -58,15 +60,18 @@ swfdec_load_object_ondata (SwfdecLoadObj
 
   if (load_object->text) {
     SWFDEC_AS_VALUE_SET_STRING (&val,
-	swfdec_as_context_get_string (SWFDEC_AS_OBJECT (load_object->target)->context, load_object->text));
+	swfdec_as_context_get_string (load_object->target->context,
+	  load_object->text));
   } else {
     SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
   }
-  swfdec_as_object_call (load_object->target, SWFDEC_AS_STR_onData, 1, &val, NULL);
+  swfdec_as_object_call (load_object->target, SWFDEC_AS_STR_onData, 1, &val,
+      NULL);
 }
 
 static void
-swfdec_load_object_loader_target_error (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+swfdec_load_object_loader_target_error (SwfdecLoaderTarget *target,
+    SwfdecLoader *loader)
 {
   SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
 
@@ -79,7 +84,8 @@ swfdec_load_object_loader_target_error (
 }
 
 static void
-swfdec_load_object_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+swfdec_load_object_loader_target_eof (SwfdecLoaderTarget *target,
+    SwfdecLoader *loader)
 {
   SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
   guint size;
@@ -173,8 +179,10 @@ swfdec_load_object_load (SwfdecLoadObjec
   g_return_if_fail (url != NULL);
 
   swfdec_load_object_reset (load_object);
-  load_object->loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (load_object)->context), url);
-  swfdec_loader_set_target (load_object->loader, SWFDEC_LOADER_TARGET (load_object));
+  load_object->loader = swfdec_player_load (
+      SWFDEC_PLAYER (SWFDEC_AS_OBJECT (load_object)->context), url);
+  swfdec_loader_set_target (load_object->loader,
+      SWFDEC_LOADER_TARGET (load_object));
   swfdec_loader_set_data_type (load_object->loader, SWFDEC_LOADER_DATA_TEXT);
 
   SWFDEC_AS_VALUE_SET_INT (&val, 0);
@@ -193,7 +201,8 @@ swfdec_load_object_new (SwfdecAsObject *
   if (!swfdec_as_context_use_mem (target->context, sizeof (SwfdecLoadObject)))
     return NULL;
   load_object = g_object_new (SWFDEC_TYPE_LOAD_OBJECT, NULL);
-  swfdec_as_object_add (load_object, target->context, sizeof (SwfdecLoadObject));
+  swfdec_as_object_add (load_object, target->context,
+      sizeof (SwfdecLoadObject));
 
   SWFDEC_LOAD_OBJECT (load_object)->target = target;
 
diff --git a/libswfdec/swfdec_load_object_as.c b/libswfdec/swfdec_load_object_as.c
index 740c4de..e4ab4de 100644
--- a/libswfdec/swfdec_load_object_as.c
+++ b/libswfdec/swfdec_load_object_as.c
@@ -31,7 +31,8 @@
 
 SWFDEC_AS_NATIVE (301, 0, swfdec_load_object_load)
 void
-swfdec_load_object_load (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
+swfdec_load_object_load (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc,
+    SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
   const char *url;
 
diff-tree e068c79c89238e20d94e93992489aef7a078fada (from 962fb2b3504c1e3205f80a8e66f1a5ba9f8b104b)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 14:02:41 2007 +0300

    Set _bytesLoaded to 0 when LoadObject is started

diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
index b570849..ae017e2 100644
--- a/libswfdec/swfdec_load_object.c
+++ b/libswfdec/swfdec_load_object.c
@@ -42,7 +42,7 @@ swfdec_load_object_loader_target_parse (
     SwfdecLoader *loader)
 {
   SwfdecAsValue val;
-  SwfdecLoadObject *object = SWFDEC_LOAD_OBJECT (target)->target;
+  SwfdecAsObject *object = SWFDEC_LOAD_OBJECT (target)->target;
 
   SWFDEC_AS_VALUE_SET_INT (&val, swfdec_loader_get_loaded (loader));
   swfdec_as_object_set_variable (object, SWFDEC_AS_STR__bytesLoaded, &val);
@@ -167,6 +167,8 @@ swfdec_load_object_init (SwfdecLoadObjec
 static void
 swfdec_load_object_load (SwfdecLoadObject *load_object, const char *url)
 {
+  SwfdecAsValue val;
+
   g_return_if_fail (SWFDEC_IS_LOAD_OBJECT (load_object));
   g_return_if_fail (url != NULL);
 
@@ -174,6 +176,10 @@ swfdec_load_object_load (SwfdecLoadObjec
   load_object->loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (load_object)->context), url);
   swfdec_loader_set_target (load_object->loader, SWFDEC_LOADER_TARGET (load_object));
   swfdec_loader_set_data_type (load_object->loader, SWFDEC_LOADER_DATA_TEXT);
+
+  SWFDEC_AS_VALUE_SET_INT (&val, 0);
+  swfdec_as_object_set_variable (load_object->target,
+      SWFDEC_AS_STR__bytesLoaded, &val);
 }
 
 SwfdecAsObject *
diff-tree 962fb2b3504c1e3205f80a8e66f1a5ba9f8b104b (from 0c9f29a8c03fea12e171e839cbc26df4d57705cf)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 12:24:03 2007 +0300

    Set _bytesLoaded and _bytesTotal properties in LoadObject

diff --git a/libswfdec/swfdec_as_strings.c b/libswfdec/swfdec_as_strings.c
index 75589b7..7674f3b 100644
--- a/libswfdec/swfdec_as_strings.c
+++ b/libswfdec/swfdec_as_strings.c
@@ -250,6 +250,8 @@ const char swfdec_as_strings[] = 
   SWFDEC_AS_CONSTANT_STRING ("yMin")
   SWFDEC_AS_CONSTANT_STRING ("yMax")
   SWFDEC_AS_CONSTANT_STRING ("close")
+  SWFDEC_AS_CONSTANT_STRING ("_bytesLoaded")
+  SWFDEC_AS_CONSTANT_STRING ("_bytesTotal")
   /* add more here */
 ;
 
diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
index 7085397..b570849 100644
--- a/libswfdec/swfdec_load_object.c
+++ b/libswfdec/swfdec_load_object.c
@@ -38,6 +38,20 @@ swfdec_load_object_loader_target_get_pla
 }
 
 static void
+swfdec_load_object_loader_target_parse (SwfdecLoaderTarget *target,
+    SwfdecLoader *loader)
+{
+  SwfdecAsValue val;
+  SwfdecLoadObject *object = SWFDEC_LOAD_OBJECT (target)->target;
+
+  SWFDEC_AS_VALUE_SET_INT (&val, swfdec_loader_get_loaded (loader));
+  swfdec_as_object_set_variable (object, SWFDEC_AS_STR__bytesLoaded, &val);
+
+  SWFDEC_AS_VALUE_SET_INT (&val, swfdec_loader_get_size (loader));
+  swfdec_as_object_set_variable (object, SWFDEC_AS_STR__bytesTotal, &val);
+}
+
+static void
 swfdec_load_object_ondata (SwfdecLoadObject *load_object)
 {
   SwfdecAsValue val;
@@ -48,7 +62,7 @@ swfdec_load_object_ondata (SwfdecLoadObj
   } else {
     SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
   }
-  swfdec_as_object_call (SWFDEC_AS_OBJECT (load_object->target), SWFDEC_AS_STR_onData, 1, &val, NULL);
+  swfdec_as_object_call (load_object->target, SWFDEC_AS_STR_onData, 1, &val, NULL);
 }
 
 static void
@@ -105,6 +119,7 @@ static void
 swfdec_load_object_loader_target_init (SwfdecLoaderTargetInterface *iface)
 {
   iface->get_player = swfdec_load_object_loader_target_get_player;
+  iface->parse = swfdec_load_object_loader_target_parse;
   iface->eof = swfdec_load_object_loader_target_eof;
   iface->error = swfdec_load_object_loader_target_error;
 }
diff-tree 0c9f29a8c03fea12e171e839cbc26df4d57705cf (from c7b0dabb45c6522f1cb4413a2f997dd2be63568f)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 12:01:10 2007 +0300

    Move XML.load code to new LoadObject class, make it work with any Object

diff --git a/libswfdec/Makefile.am b/libswfdec/Makefile.am
index 2f48811..85ec276 100644
--- a/libswfdec/Makefile.am
+++ b/libswfdec/Makefile.am
@@ -74,6 +74,8 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_image.c \
 	swfdec_interval.c \
 	swfdec_key_as.c \
+	swfdec_load_object.c \
+	swfdec_load_object_as.c \
 	swfdec_loader.c \
 	swfdec_loadertarget.c \
 	swfdec_marshal.c \
@@ -107,7 +109,6 @@ libswfdec_ at SWFDEC_MAJORMINOR@_la_SOURCES
 	swfdec_video.c \
 	swfdec_video_movie.c \
 	swfdec_video_movie_as.c \
-	swfdec_xml.c \
 	swfdec_xml_as.c
 
 libswfdec_ at SWFDEC_MAJORMINOR@_la_CFLAGS = \
@@ -187,6 +188,8 @@ noinst_HEADERS = \
 	swfdec_initialize.h \
 	swfdec_internal.h \
 	swfdec_interval.h \
+	swfdec_load_object.h \
+	swfdec_load_object_as.h \
 	swfdec_loader_internal.h \
 	swfdec_loadertarget.h \
 	swfdec_marshal.h \
@@ -213,7 +216,7 @@ noinst_HEADERS = \
 	swfdec_utils.h \
 	swfdec_video.h \
 	swfdec_video_movie.h \
-	swfdec_xml.h
+	swfdec_xml_as.h
 
 EXTRA_DIST = \
 	compiler.c \
diff --git a/libswfdec/swfdec_load_object.c b/libswfdec/swfdec_load_object.c
new file mode 100644
index 0000000..7085397
--- /dev/null
+++ b/libswfdec/swfdec_load_object.c
@@ -0,0 +1,185 @@
+/* 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 <string.h>
+#include "swfdec_load_object.h"
+#include "swfdec_as_strings.h"
+#include "swfdec_debug.h"
+#include "swfdec_loader_internal.h"
+#include "swfdec_loadertarget.h"
+#include "swfdec_player_internal.h"
+
+/*** SWFDEC_LOADER_TARGET ***/
+
+static SwfdecPlayer *
+swfdec_load_object_loader_target_get_player (SwfdecLoaderTarget *target)
+{
+  return SWFDEC_PLAYER (SWFDEC_AS_OBJECT (target)->context);
+}
+
+static void
+swfdec_load_object_ondata (SwfdecLoadObject *load_object)
+{
+  SwfdecAsValue val;
+
+  if (load_object->text) {
+    SWFDEC_AS_VALUE_SET_STRING (&val,
+	swfdec_as_context_get_string (SWFDEC_AS_OBJECT (load_object->target)->context, load_object->text));
+  } else {
+    SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
+  }
+  swfdec_as_object_call (SWFDEC_AS_OBJECT (load_object->target), SWFDEC_AS_STR_onData, 1, &val, NULL);
+}
+
+static void
+swfdec_load_object_loader_target_error (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+{
+  SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
+
+  /* break reference to the loader */
+  swfdec_loader_set_target (loader, NULL);
+  load_object->loader = NULL;
+  g_object_unref (loader);
+  /* emit onData */
+  swfdec_load_object_ondata (load_object);
+}
+
+static void
+swfdec_load_object_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loader)
+{
+  SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
+  guint size;
+
+  /* get the text from the loader */
+  size = swfdec_buffer_queue_get_depth (loader->queue);
+  load_object->text = g_try_malloc (size + 1);
+  if (load_object->text) {
+    SwfdecBuffer *buffer;
+    guint i = 0;
+    while ((buffer = swfdec_buffer_queue_pull_buffer (loader->queue))) {
+      memcpy (load_object->text + i, buffer->data, buffer->length);
+      i += buffer->length;
+      swfdec_buffer_unref (buffer);
+    }
+    g_assert (i == size);
+    load_object->text[size] = '\0';
+    /* FIXME: validate otherwise? */
+    if (!g_utf8_validate (load_object->text, size, NULL)) {
+      SWFDEC_ERROR ("downloaded data is not valid utf-8");
+      g_free (load_object->text);
+      load_object->text = NULL;
+    }
+  } else {
+    SWFDEC_ERROR ("not enough memory to copy %u bytes", size);
+  }
+
+  /* break reference to the loader */
+  swfdec_loader_set_target (loader, NULL);
+  load_object->loader = NULL;
+  g_object_unref (loader);
+  /* emit onData */
+  swfdec_load_object_ondata (load_object);
+}
+
+static void
+swfdec_load_object_loader_target_init (SwfdecLoaderTargetInterface *iface)
+{
+  iface->get_player = swfdec_load_object_loader_target_get_player;
+  iface->eof = swfdec_load_object_loader_target_eof;
+  iface->error = swfdec_load_object_loader_target_error;
+}
+
+/*** SWFDEC_LOAD_OBJECT ***/
+
+G_DEFINE_TYPE_WITH_CODE (SwfdecLoadObject, swfdec_load_object, SWFDEC_TYPE_AS_OBJECT,
+    G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_load_object_loader_target_init))
+
+static void
+swfdec_load_object_reset (SwfdecLoadObject *load_object)
+{
+  if (load_object->loader) {
+    swfdec_loader_set_target (load_object->loader, NULL);
+    g_object_unref (load_object->loader);
+    load_object->loader = NULL;
+  }
+  g_free (load_object->text);
+  load_object->text = NULL;
+}
+
+static void
+swfdec_load_object_dispose (GObject *object)
+{
+  SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (object);
+
+  swfdec_load_object_reset (load_object);
+
+  G_OBJECT_CLASS (swfdec_load_object_parent_class)->dispose (object);
+}
+
+static void
+swfdec_load_object_class_init (SwfdecLoadObjectClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = swfdec_load_object_dispose;
+}
+
+static void
+swfdec_load_object_init (SwfdecLoadObject *load_object)
+{
+}
+
+static void
+swfdec_load_object_load (SwfdecLoadObject *load_object, const char *url)
+{
+  g_return_if_fail (SWFDEC_IS_LOAD_OBJECT (load_object));
+  g_return_if_fail (url != NULL);
+
+  swfdec_load_object_reset (load_object);
+  load_object->loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (load_object)->context), url);
+  swfdec_loader_set_target (load_object->loader, SWFDEC_LOADER_TARGET (load_object));
+  swfdec_loader_set_data_type (load_object->loader, SWFDEC_LOADER_DATA_TEXT);
+}
+
+SwfdecAsObject *
+swfdec_load_object_new (SwfdecAsObject *target, const char *url)
+{
+  SwfdecAsObject *load_object;
+
+  g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (target), NULL);
+  g_return_val_if_fail (url != NULL, NULL);
+
+  if (!swfdec_as_context_use_mem (target->context, sizeof (SwfdecLoadObject)))
+    return NULL;
+  load_object = g_object_new (SWFDEC_TYPE_LOAD_OBJECT, NULL);
+  swfdec_as_object_add (load_object, target->context, sizeof (SwfdecLoadObject));
+
+  SWFDEC_LOAD_OBJECT (load_object)->target = target;
+
+  SWFDEC_PLAYER (target->context)->load_objects =
+    g_list_append (SWFDEC_PLAYER (target->context)->load_objects, load_object);
+
+  swfdec_load_object_load (SWFDEC_LOAD_OBJECT (load_object), url);
+
+  return load_object;
+}
diff --git a/libswfdec/swfdec_load_object.h b/libswfdec/swfdec_load_object.h
new file mode 100644
index 0000000..9a07b59
--- /dev/null
+++ b/libswfdec/swfdec_load_object.h
@@ -0,0 +1,58 @@
+/* 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_LOAD_OBJECT_H_
+#define _SWFDEC_LOAD_OBJECT_H_
+
+#include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_as_object.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _SwfdecLoadObject SwfdecLoadObject;
+typedef struct _SwfdecLoadObjectClass SwfdecLoadObjectClass;
+
+#define SWFDEC_TYPE_LOAD_OBJECT                    (swfdec_load_object_get_type())
+#define SWFDEC_IS_LOAD_OBJECT(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_LOAD_OBJECT))
+#define SWFDEC_IS_LOAD_OBJECT_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_LOAD_OBJECT))
+#define SWFDEC_LOAD_OBJECT(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_LOAD_OBJECT, SwfdecLoadObject))
+#define SWFDEC_LOAD_OBJECT_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_LOAD_OBJECT, SwfdecLoadObjectClass))
+#define SWFDEC_LOAD_OBJECT_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_LOAD_OBJECT, SwfdecLoadObjectClass))
+
+struct _SwfdecLoadObject {
+  SwfdecAsObject	object;
+
+  SwfdecAsObject	*target;	/* target object */
+  char *		text;		/* string that this LOAD_OBJECT displays */
+  SwfdecLoader *	loader;		/* loader when loading or NULL */
+};
+
+struct _SwfdecLoadObjectClass {
+  SwfdecAsObjectClass	object_class;
+};
+
+GType		swfdec_load_object_get_type	(void);
+
+SwfdecAsObject *swfdec_load_object_new		(SwfdecAsObject *	target,
+						 const char *		url);
+
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_load_object_as.c b/libswfdec/swfdec_load_object_as.c
new file mode 100644
index 0000000..740c4de
--- /dev/null
+++ b/libswfdec/swfdec_load_object_as.c
@@ -0,0 +1,40 @@
+/* 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 <string.h>
+#include "swfdec_load_object.h"
+#include "swfdec_as_strings.h"
+#include "swfdec_debug.h"
+#include "swfdec_loader_internal.h"
+#include "swfdec_loadertarget.h"
+#include "swfdec_player_internal.h"
+
+SWFDEC_AS_NATIVE (301, 0, swfdec_load_object_load)
+void
+swfdec_load_object_load (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
+{
+  const char *url;
+
+  url = swfdec_as_value_to_string (cx, &argv[0]);
+  swfdec_load_object_new (obj, url);
+}
diff --git a/libswfdec/swfdec_load_object_as.h b/libswfdec/swfdec_load_object_as.h
new file mode 100644
index 0000000..f14f0e2
--- /dev/null
+++ b/libswfdec/swfdec_load_object_as.h
@@ -0,0 +1,31 @@
+/* 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_LOADABLE_H_
+#define _SWFDEC_LOADABLE_H_
+
+#include <libswfdec/swfdec.h>
+#include <libswfdec/swfdec_as_object.h>
+
+G_BEGIN_DECLS
+
+void swfdec_load_object_load (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval);
+
+G_END_DECLS
+#endif
diff --git a/libswfdec/swfdec_player.c b/libswfdec/swfdec_player.c
index 98ded92..39a1cb1 100644
--- a/libswfdec/swfdec_player.c
+++ b/libswfdec/swfdec_player.c
@@ -38,6 +38,7 @@
 #include "swfdec_initialize.h"
 #include "swfdec_internal.h"
 #include "swfdec_loader_internal.h"
+#include "swfdec_load_object.h"
 #include "swfdec_marshal.h"
 #include "swfdec_movie.h"
 #include "swfdec_script.h"
@@ -1095,6 +1096,10 @@ swfdec_player_mark (SwfdecAsContext *con
   for (walk = player->roots; walk; walk = walk->next) {
     swfdec_as_object_mark (walk->data);
   }
+  for (walk = player->load_objects; walk; walk = walk->next) {
+    swfdec_as_object_mark (walk->data);
+    swfdec_as_object_mark (SWFDEC_LOAD_OBJECT (walk->data)->target);
+  }
 
   SWFDEC_AS_CONTEXT_CLASS (swfdec_player_parent_class)->mark (context);
 }
diff --git a/libswfdec/swfdec_player_internal.h b/libswfdec/swfdec_player_internal.h
index 0d27ec8..45d9103 100644
--- a/libswfdec/swfdec_player_internal.h
+++ b/libswfdec/swfdec_player_internal.h
@@ -56,6 +56,7 @@ struct _SwfdecPlayer
   guint			width;			/* width of movie */
   guint			height;			/* height of movie */
   GList *		roots;			/* all the root movies */
+  GList *		load_objects;		/* all the load objects */
   SwfdecCache *		cache;			/* player cache */
   gboolean		bgcolor_set;		/* TRUE if the background color has been set */
   SwfdecColor		bgcolor;		/* background color */
diff --git a/libswfdec/swfdec_xml.c b/libswfdec/swfdec_xml.c
deleted file mode 100644
index c418ca4..0000000
--- a/libswfdec/swfdec_xml.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* 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 <string.h>
-#include "swfdec_xml.h"
-#include "swfdec_as_strings.h"
-#include "swfdec_debug.h"
-#include "swfdec_loader_internal.h"
-#include "swfdec_loadertarget.h"
-#include "swfdec_player_internal.h"
-
-/*** SWFDEC_LOADER_TARGET ***/
-
-static SwfdecPlayer *
-swfdec_xml_loader_target_get_player (SwfdecLoaderTarget *target)
-{
-  return SWFDEC_PLAYER (SWFDEC_AS_OBJECT (target)->context);
-}
-
-static void
-swfdec_xml_ondata (SwfdecXml *xml)
-{
-  SwfdecAsValue val;
-
-  if (xml->text) {
-    SWFDEC_AS_VALUE_SET_STRING (&val,
-	swfdec_as_context_get_string (SWFDEC_AS_OBJECT (xml)->context, xml->text));
-  } else {
-    SWFDEC_AS_VALUE_SET_UNDEFINED (&val);
-  }
-  swfdec_as_object_call (SWFDEC_AS_OBJECT (xml), SWFDEC_AS_STR_onData, 1, &val, NULL);
-}
-
-static void
-swfdec_xml_loader_target_error (SwfdecLoaderTarget *target, SwfdecLoader *loader)
-{
-  SwfdecXml *xml = SWFDEC_XML (target);
-
-  /* break reference to the loader */
-  swfdec_loader_set_target (loader, NULL);
-  xml->loader = NULL;
-  g_object_unref (loader);
-  /* emit onData */
-  swfdec_xml_ondata (xml);
-}
-
-static void
-swfdec_xml_loader_target_eof (SwfdecLoaderTarget *target, SwfdecLoader *loader)
-{
-  SwfdecXml *xml = SWFDEC_XML (target);
-  guint size;
-
-  /* get the text from the loader */
-  size = swfdec_buffer_queue_get_depth (loader->queue);
-  xml->text = g_try_malloc (size + 1);
-  if (xml->text) {
-    SwfdecBuffer *buffer;
-    guint i = 0;
-    while ((buffer = swfdec_buffer_queue_pull_buffer (loader->queue))) {
-      memcpy (xml->text + i, buffer->data, buffer->length);
-      i += buffer->length;
-      swfdec_buffer_unref (buffer);
-    }
-    g_assert (i == size);
-    xml->text[size] = '\0';
-    /* FIXME: validate otherwise? */
-    if (!g_utf8_validate (xml->text, size, NULL)) {
-      SWFDEC_ERROR ("downloaded data is not valid utf-8");
-      g_free (xml->text);
-      xml->text = NULL;
-    }
-  } else {
-    SWFDEC_ERROR ("not enough memory to copy %u bytes", size);
-  }
-
-  /* break reference to the loader */
-  swfdec_loader_set_target (loader, NULL);
-  xml->loader = NULL;
-  g_object_unref (loader);
-  /* emit onData */
-  swfdec_xml_ondata (xml);
-}
-
-static void
-swfdec_xml_loader_target_init (SwfdecLoaderTargetInterface *iface)
-{
-  iface->get_player = swfdec_xml_loader_target_get_player;
-  iface->eof = swfdec_xml_loader_target_eof;
-  iface->error = swfdec_xml_loader_target_error;
-}
-
-/*** SWFDEC_XML ***/
-
-G_DEFINE_TYPE_WITH_CODE (SwfdecXml, swfdec_xml, SWFDEC_TYPE_AS_OBJECT,
-    G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_xml_loader_target_init))
-
-static void
-swfdec_xml_reset (SwfdecXml *xml)
-{
-  if (xml->loader) {
-    swfdec_loader_set_target (xml->loader, NULL);
-    g_object_unref (xml->loader);
-    xml->loader = NULL;
-  }
-  g_free (xml->text);
-  xml->text = NULL;
-}
-
-static void
-swfdec_xml_dispose (GObject *object)
-{
-  SwfdecXml *xml = SWFDEC_XML (object);
-
-  swfdec_xml_reset (xml);
-
-  G_OBJECT_CLASS (swfdec_xml_parent_class)->dispose (object);
-}
-
-static void
-swfdec_xml_class_init (SwfdecXmlClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->dispose = swfdec_xml_dispose;
-}
-
-static void
-swfdec_xml_init (SwfdecXml *xml)
-{
-}
-
-SwfdecAsObject *
-swfdec_xml_new (SwfdecAsContext *context)
-{
-  SwfdecAsObject *xml;
-
-  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
-
-  if (!swfdec_as_context_use_mem (context, sizeof (SwfdecXml)))
-    return NULL;
-  xml = g_object_new (SWFDEC_TYPE_XML, NULL);
-  swfdec_as_object_add (xml, context, sizeof (SwfdecXml));
-
-  return xml;
-}
-
-void
-swfdec_xml_load (SwfdecXml *xml, const char *url)
-{
-  g_return_if_fail (SWFDEC_IS_XML (xml));
-  g_return_if_fail (url != NULL);
-
-  swfdec_xml_reset (xml);
-  xml->loader = swfdec_player_load (SWFDEC_PLAYER (SWFDEC_AS_OBJECT (xml)->context), url);
-  swfdec_loader_set_target (xml->loader, SWFDEC_LOADER_TARGET (xml));
-  swfdec_loader_set_data_type (xml->loader, SWFDEC_LOADER_DATA_TEXT);
-}
diff --git a/libswfdec/swfdec_xml.h b/libswfdec/swfdec_xml.h
deleted file mode 100644
index 77b355a..0000000
--- a/libswfdec/swfdec_xml.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 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_XML_H_
-#define _SWFDEC_XML_H_
-
-#include <libswfdec/swfdec.h>
-#include <libswfdec/swfdec_as_object.h>
-
-G_BEGIN_DECLS
-
-
-typedef struct _SwfdecXml SwfdecXml;
-typedef struct _SwfdecXmlClass SwfdecXmlClass;
-
-#define SWFDEC_TYPE_XML                    (swfdec_xml_get_type())
-#define SWFDEC_IS_XML(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_XML))
-#define SWFDEC_IS_XML_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_XML))
-#define SWFDEC_XML(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_XML, SwfdecXml))
-#define SWFDEC_XML_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_XML, SwfdecXmlClass))
-#define SWFDEC_XML_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_XML, SwfdecXmlClass))
-
-struct _SwfdecXml {
-  SwfdecAsObject	object;
-
-  char *		text;		/* string that this XML displays */
-  SwfdecLoader *	loader;		/* loader when loading or NULL */
-};
-
-struct _SwfdecXmlClass {
-  SwfdecAsObjectClass	object_class;
-};
-
-GType		swfdec_xml_get_type	(void);
-
-SwfdecAsObject *swfdec_xml_new		(SwfdecAsContext *	context);
-
-void		swfdec_xml_load		(SwfdecXml *		xml,
-					 const char *		url);
-
-
-G_END_DECLS
-#endif
diff --git a/libswfdec/swfdec_xml_as.c b/libswfdec/swfdec_xml_as.c
index 8159977..10f9d13 100644
--- a/libswfdec/swfdec_xml_as.c
+++ b/libswfdec/swfdec_xml_as.c
@@ -21,22 +21,25 @@
 #include "config.h"
 #endif
 
-#include "swfdec_xml.h"
+#include "swfdec_xml_as.h"
 #include "swfdec_as_native_function.h"
 #include "swfdec_as_object.h"
 #include "swfdec_as_strings.h"
 #include "swfdec_debug.h"
 #include "swfdec_internal.h"
 #include "swfdec_player_internal.h"
+#include "swfdec_load_object_as.h"
+
+G_DEFINE_TYPE (SwfdecXml, swfdec_xml, SWFDEC_TYPE_AS_OBJECT)
 
 static void
-swfdec_xml_do_load (SwfdecAsContext *cx, SwfdecAsObject *obj, guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
+swfdec_xml_class_init (SwfdecXmlClass *klass)
 {
-  SwfdecXml *xml = SWFDEC_XML (obj);
-  const char *url;
+}
 
-  url = swfdec_as_value_to_string (cx, &argv[0]);
-  swfdec_xml_load (xml, url);
+static void
+swfdec_xml_init (SwfdecXml *xml)
+{
 }
 
 void
@@ -62,6 +65,6 @@ swfdec_xml_init_context (SwfdecPlayer *p
   SWFDEC_AS_VALUE_SET_OBJECT (&val, xml);
   swfdec_as_object_set_variable (proto, SWFDEC_AS_STR_constructor, &val);
   swfdec_as_object_add_function (proto, SWFDEC_AS_STR_load, SWFDEC_TYPE_XML,
-      swfdec_xml_do_load, 1);
+      swfdec_load_object_load, 1);
 }
 
diff --git a/libswfdec/swfdec_xml_as.h b/libswfdec/swfdec_xml_as.h
new file mode 100644
index 0000000..1681a8f
--- /dev/null
+++ b/libswfdec/swfdec_xml_as.h
@@ -0,0 +1,51 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ *		 2007 Pekka Lampila <pekka.lampila at iki.fi>
+ *
+ * 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_XML_H_
+#define _SWFDEC_XML_H_
+
+#include <libswfdec/swfdec_as_object.h>
+#include <libswfdec/swfdec_types.h>
+#include <libswfdec/swfdec_script.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecXml SwfdecXml;
+typedef struct _SwfdecXmlClass SwfdecXmlClass;
+
+#define SWFDEC_TYPE_XML                    (swfdec_xml_get_type())
+#define SWFDEC_IS_XML(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_XML))
+#define SWFDEC_IS_XML_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_XML))
+#define SWFDEC_XML(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_XML, SwfdecXml))
+#define SWFDEC_XML_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_XML, SwfdecXmlClass))
+#define SWFDEC_XML_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_XML, SwfdecXmlClass))
+
+struct _SwfdecXml {
+  SwfdecAsObject	object;
+};
+
+struct _SwfdecXmlClass {
+  SwfdecAsObjectClass	object_class;
+};
+
+GType		swfdec_xml_get_type	(void);
+
+G_END_DECLS
+#endif
diff-tree c7b0dabb45c6522f1cb4413a2f997dd2be63568f (from 223cc7d4adec6429f56efa8750e04345ccd85bfd)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 00:51:22 2007 +0300

    Forgot to add forin-delete test to Makefile.am (sigh)

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 9f3becf..794e7f1 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -380,6 +380,13 @@ EXTRA_DIST = \
 	function-tostring-7.swf.trace \
 	function-undefined.swf \
 	function-undefined.swf.trace \
+	forin-delete.as \
+	forin-delete-5.swf \
+	forin-delete-5.swf.trace \
+	forin-delete-6.swf \
+	forin-delete-6.swf.trace \
+	forin-delete-7.swf \
+	forin-delete-7.swf.trace \
 	goto1.swf \
 	goto1.swf.trace \
 	goto2.swf \
diff-tree 223cc7d4adec6429f56efa8750e04345ccd85bfd (from 76e35412ea974749804920a47678db8c1242487b)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Wed Jul 18 19:56:45 2007 +0300

    Implement hitTest for x, y coordinates (without shapeFlag)

diff --git a/libswfdec/swfdec_sprite_movie_as.c b/libswfdec/swfdec_sprite_movie_as.c
index f18597c..5eea43f 100644
--- a/libswfdec/swfdec_sprite_movie_as.c
+++ b/libswfdec/swfdec_sprite_movie_as.c
@@ -208,8 +208,31 @@ swfdec_sprite_movie_hitTest (SwfdecAsCon
 	SWFDEC_OBJECT (other)->extents.x1, SWFDEC_OBJECT (other)->extents.y1);
 #endif
     SWFDEC_AS_VALUE_SET_BOOLEAN (rval, swfdec_rect_intersect (NULL, &movie_rect, &other_rect));
+  } else if (argc >= 2) {
+    SwfdecRect movie_rect;
+    double x, y;
+
+    x = swfdec_as_value_to_number (cx, &argv[0]);
+    y = swfdec_as_value_to_number (cx, &argv[1]);
+
+    if (argc >= 3) {
+      if (swfdec_as_value_to_boolean (cx, &argv[2])) {
+	SWFDEC_FIXME ("hitTest's shapeFlag parameter not supported");
+	// just continue...
+      }
+    }
+
+    swfdec_movie_update (movie);
+    movie_rect = movie->original_extents;
+    while (movie->parent) {
+      swfdec_rect_transform (&movie_rect, &movie_rect, &movie->matrix);
+      movie = movie->parent;
+    }
+
+    SWFDEC_AS_VALUE_SET_BOOLEAN (rval, swfdec_rect_contains (&movie_rect,
+	  SWFDEC_PLAYER (cx)->mouse_x, SWFDEC_PLAYER (cx)->mouse_y));
   } else {
-    SWFDEC_ERROR ("hitTest for x, y coordinate not implemented");
+    SWFDEC_FIXME ("hitText with 0 parameters, what to do?");
   }
 }
 
diff-tree 76e35412ea974749804920a47678db8c1242487b (from db0818e50daf6422c947fba7a38aaccef6d6f070)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 00:45:41 2007 +0300

    Add test for deleting properties when in for in loop

diff --git a/test/trace/forin-delete-5.swf b/test/trace/forin-delete-5.swf
new file mode 100644
index 0000000..8dcd58a
Binary files /dev/null and b/test/trace/forin-delete-5.swf differ
diff --git a/test/trace/forin-delete-5.swf.trace b/test/trace/forin-delete-5.swf.trace
new file mode 100644
index 0000000..c970f17
--- /dev/null
+++ b/test/trace/forin-delete-5.swf.trace
@@ -0,0 +1 @@
+0,1,2,3,4,5,6,7,8,9
diff --git a/test/trace/forin-delete-6.swf b/test/trace/forin-delete-6.swf
new file mode 100644
index 0000000..c2ed5d5
Binary files /dev/null and b/test/trace/forin-delete-6.swf differ
diff --git a/test/trace/forin-delete-6.swf.trace b/test/trace/forin-delete-6.swf.trace
new file mode 100644
index 0000000..c970f17
--- /dev/null
+++ b/test/trace/forin-delete-6.swf.trace
@@ -0,0 +1 @@
+0,1,2,3,4,5,6,7,8,9
diff --git a/test/trace/forin-delete-7.swf b/test/trace/forin-delete-7.swf
new file mode 100644
index 0000000..07e6f12
Binary files /dev/null and b/test/trace/forin-delete-7.swf differ
diff --git a/test/trace/forin-delete-7.swf.trace b/test/trace/forin-delete-7.swf.trace
new file mode 100644
index 0000000..c970f17
--- /dev/null
+++ b/test/trace/forin-delete-7.swf.trace
@@ -0,0 +1 @@
+0,1,2,3,4,5,6,7,8,9
diff --git a/test/trace/forin-delete.as b/test/trace/forin-delete.as
new file mode 100644
index 0000000..696fdaf
--- /dev/null
+++ b/test/trace/forin-delete.as
@@ -0,0 +1,14 @@
+// makeswf -v 7 -r 1 -o forin-delete-7.swf forin-delete.as
+
+obj = new Object ();
+for (var i = 0; i < 10; i++) {
+  obj[i] = "something";
+}
+a = new Array();
+for (var prop in obj) {
+  a.push (prop);
+  delete obj[prop];
+}
+trace (a.sort ());
+
+loadMovie ("FSCommand:quit", "");
diff-tree db0818e50daf6422c947fba7a38aaccef6d6f070 (from af55385468269795f5f4d14cb8746dfd3d7be245)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Sat Aug 18 00:44:10 2007 +0300

    Forgot to add propflags test to Makefile.am

diff --git a/test/trace/Makefile.am b/test/trace/Makefile.am
index 45b56a8..9f3becf 100644
--- a/test/trace/Makefile.am
+++ b/test/trace/Makefile.am
@@ -787,6 +787,13 @@ EXTRA_DIST = \
 	prototype-movie-8.swf.trace \
 	prototypes.swf \
 	prototypes.swf.trace \
+	propflags.as \
+	propflags-5.swf \
+	propflags-5.swf.trace \
+	propflags-6.swf \
+	propflags-6.swf.trace \
+	propflags-7.swf \
+	propflags-7.swf.trace \
 	register-count.swf \
 	register-count.swf.trace \
 	register-count.xml \
diff-tree af55385468269795f5f4d14cb8746dfd3d7be245 (from 616cfc32ab9acfa67d4d3c9c963ae76d29ac5835)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 23:38:48 2007 +0200

    fix docs

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index a5e4b08..8d4df41 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -61,11 +61,11 @@
 
 /**
  * SwfdecAsVariableFlag:
- * @SWFDEC_AS_VARIABLE_DONT_ENUM: Do not include variable in enumerations and
+ * @SWFDEC_AS_VARIABLE_HIDDEN: Do not include variable in enumerations and
  *                                swfdec_as_object_foreach().
  * @SWFDEC_AS_VARIABLE_PERMANENT: Do not all swfdec_as_object_delete_variable()
  *                                to delete this variable.
- * @SWFDEC_AS_VARIABLE_READONLY: Do not allow changing the value with
+ * @SWFDEC_AS_VARIABLE_CONSTANT: Do not allow changing the value with
  *                               swfdec_as_object_set_variable().
  *
  * These flags are used to describe various properties of a variable inside
diff-tree 616cfc32ab9acfa67d4d3c9c963ae76d29ac5835 (from b1ceea248f70bb55ebc8b0874491ef9b84bed2ba)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 23:30:59 2007 +0200

    ActionDelete and ActionDelete2 push TRUE or FALSE back to the success

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index f9a2cc2..3b7c01f 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1709,22 +1709,25 @@ swfdec_action_delete (SwfdecAsContext *c
 {
   SwfdecAsValue *val;
   const char *name;
+  gboolean success = FALSE;
   
   name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));
   val = swfdec_as_stack_peek (cx, 2);
   if (SWFDEC_AS_VALUE_IS_OBJECT (val))
-    swfdec_as_object_delete_variable (SWFDEC_AS_VALUE_GET_OBJECT (val), name);
-  swfdec_as_stack_pop_n (cx, 2);
+    success = swfdec_as_object_delete_variable (SWFDEC_AS_VALUE_GET_OBJECT (val), name);
+  SWFDEC_AS_VALUE_SET_BOOLEAN (val, success);
+  swfdec_as_stack_pop_n (cx, 1);
 }
 
 static void
 swfdec_action_delete2 (SwfdecAsContext *cx, guint action, const guint8 *data, guint len)
 {
+  SwfdecAsValue *val;
   const char *name;
   
-  name = swfdec_as_value_to_string (cx, swfdec_as_stack_peek (cx, 1));
-  swfdec_as_frame_delete_variable (cx->frame, name);
-  swfdec_as_stack_pop (cx);
+  val = swfdec_as_stack_peek (cx, 1);
+  name = swfdec_as_value_to_string (cx, val);
+  SWFDEC_AS_VALUE_SET_BOOLEAN (val, swfdec_as_frame_delete_variable (cx->frame, name));
 }
 
 static void
@@ -2487,8 +2490,8 @@ const SwfdecActionSpec swfdec_as_actions
   [SWFDEC_AS_ACTION_MB_CHAR_TO_ASCII] = { "MBCharToAscii", NULL },
   [SWFDEC_AS_ACTION_MB_ASCII_TO_CHAR] = { "MBAsciiToChar", NULL, 1, 1, { NULL, swfdec_action_mb_ascii_to_char_5, swfdec_action_mb_ascii_to_char_5, swfdec_action_ascii_to_char, swfdec_action_ascii_to_char }  },
   /* version 5 */
-  [SWFDEC_AS_ACTION_DELETE] = { "Delete", NULL, 2, 0, { NULL, NULL, swfdec_action_delete, swfdec_action_delete, swfdec_action_delete } },
-  [SWFDEC_AS_ACTION_DELETE2] = { "Delete2", NULL, 1, 0, { NULL, NULL, swfdec_action_delete2, swfdec_action_delete2, swfdec_action_delete2 } },
+  [SWFDEC_AS_ACTION_DELETE] = { "Delete", NULL, 2, 1, { NULL, NULL, swfdec_action_delete, swfdec_action_delete, swfdec_action_delete } },
+  [SWFDEC_AS_ACTION_DELETE2] = { "Delete2", NULL, 1, 1, { NULL, NULL, swfdec_action_delete2, swfdec_action_delete2, swfdec_action_delete2 } },
   [SWFDEC_AS_ACTION_DEFINE_LOCAL] = { "DefineLocal", NULL, 2, 0, { NULL, NULL, swfdec_action_define_local, swfdec_action_define_local, swfdec_action_define_local } },
   [SWFDEC_AS_ACTION_CALL_FUNCTION] = { "CallFunction", NULL, -1, 1, { NULL, NULL, swfdec_action_call_function, swfdec_action_call_function, swfdec_action_call_function } },
   [SWFDEC_AS_ACTION_RETURN] = { "Return", NULL, 1, 0, { NULL, NULL, swfdec_action_return, swfdec_action_return, swfdec_action_return } },
diff-tree b1ceea248f70bb55ebc8b0874491ef9b84bed2ba (from 8ea0acbb24b2faaa135c7ca793483b818c5621b9)
Author: Benjamin Otte <otte at gnome.org>
Date:   Fri Aug 17 23:30:34 2007 +0200

    unused variable

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index d0017d0..75ab9d6 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -1007,8 +1007,6 @@ static void
 swfdec_as_context_ASSetPropFlags_set_one_flag (SwfdecAsObject *object,
     const char *s, guint *flags)
 {
-  guint real;
-
   swfdec_as_object_unset_variable_flags (object, s, flags[1]);
   swfdec_as_object_set_variable_flags (object, s, flags[0]);
 }
diff-tree 8ea0acbb24b2faaa135c7ca793483b818c5621b9 (from bd0bd75bc96be5c3be3a5cb3aa4c3bb26ac0a3c2)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Aug 17 22:52:50 2007 +0300

    Fix propflags test case by sorting the traced arrays.

diff --git a/test/trace/propflags-5.swf b/test/trace/propflags-5.swf
index b26242b..644c5ac 100644
Binary files a/test/trace/propflags-5.swf and b/test/trace/propflags-5.swf differ
diff --git a/test/trace/propflags-5.swf.trace b/test/trace/propflags-5.swf.trace
index 7026d1f..eeaa55a 100644
--- a/test/trace/propflags-5.swf.trace
+++ b/test/trace/propflags-5.swf.trace
@@ -1,3 +1,3 @@
-Hidden: 7,5,3,1,__constructor__,constructor,__proto__
-Constant: 7,6,5,4
+Hidden: 1,3,5,7,__constructor__,__proto__,constructor
+Constant: 4,5,6,7
 Permanent: 
diff --git a/test/trace/propflags-6.swf b/test/trace/propflags-6.swf
index 93c2e52..2af13d8 100644
Binary files a/test/trace/propflags-6.swf and b/test/trace/propflags-6.swf differ
diff --git a/test/trace/propflags-6.swf.trace b/test/trace/propflags-6.swf.trace
index a7eb732..8d59d4e 100644
--- a/test/trace/propflags-6.swf.trace
+++ b/test/trace/propflags-6.swf.trace
@@ -1,3 +1,3 @@
-Hidden: 7,5,3,1,__constructor__,constructor,__proto__
-Constant: 7,6,5,4
-Permanent: 7,6,3,2,__proto__
+Hidden: 1,3,5,7,__constructor__,__proto__,constructor
+Constant: 4,5,6,7
+Permanent: 2,3,6,7,__proto__
diff --git a/test/trace/propflags-7.swf b/test/trace/propflags-7.swf
index 9903ec0..9ae55c5 100644
Binary files a/test/trace/propflags-7.swf and b/test/trace/propflags-7.swf differ
diff --git a/test/trace/propflags-7.swf.trace b/test/trace/propflags-7.swf.trace
index 614873e..74b639d 100644
--- a/test/trace/propflags-7.swf.trace
+++ b/test/trace/propflags-7.swf.trace
@@ -1,3 +1,3 @@
-Hidden: 7,5,3,1,__constructor__,__proto__
-Constant: 7,6,5,4
-Permanent: 7,6,3,2,__proto__
+Hidden: 1,3,5,7,__constructor__,__proto__
+Constant: 4,5,6,7
+Permanent: 2,3,6,7,__proto__
diff --git a/test/trace/propflags.as b/test/trace/propflags.as
index 25ab56b..34ce251 100644
--- a/test/trace/propflags.as
+++ b/test/trace/propflags.as
@@ -19,7 +19,7 @@ function hidden_properties (obj)
   }
   ASSetPropFlags (obj, hidden, 1, 0);
 
-  return hidden;
+  return hidden.sort ();
 }
 
 // loses flags from the properties that are not permanent
@@ -44,7 +44,7 @@ function permanent_properties (obj)
   ASSetPropFlags (obj, hidden, 1, 0);
   ASSetPropFlags (obj, constant, 3, 0);
 
-  return permanent;
+  return permanent.sort ();
 }
 
 function constant_properties (obj)
@@ -67,7 +67,7 @@ function constant_properties (obj)
 
   ASSetPropFlags (obj, hidden, 1, 0);
 
-  return constant;
+  return constant.sort ();
 }
 
 var obj = new Object ();
diff-tree bd0bd75bc96be5c3be3a5cb3aa4c3bb26ac0a3c2 (from a37dad992ab5fe037d4ef153d6a80ee0327262d9)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Aug 17 21:55:16 2007 +0300

    Set __proto__ and __constructor__ properties flags

diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index 46c590d..a5e4b08 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -942,7 +942,8 @@ swfdec_as_object_create (SwfdecAsFunctio
  * object.__proto__ = construct.prototype; ]|
  **/
 void
-swfdec_as_object_set_constructor (SwfdecAsObject *object, SwfdecAsObject *construct, gboolean scripted)
+swfdec_as_object_set_constructor (SwfdecAsObject *object,
+    SwfdecAsObject *construct, gboolean scripted)
 {
   SwfdecAsValue val;
   SwfdecAsObject *proto;
@@ -950,7 +951,8 @@ swfdec_as_object_set_constructor (Swfdec
   g_return_if_fail (SWFDEC_IS_AS_OBJECT (object));
   g_return_if_fail (SWFDEC_IS_AS_OBJECT (construct));
 
-  swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (construct), SWFDEC_AS_STR_prototype, &val);
+  swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (construct),
+      SWFDEC_AS_STR_prototype, &val);
   if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
     proto = SWFDEC_AS_VALUE_GET_OBJECT (&val);
   } else {
@@ -959,8 +961,15 @@ swfdec_as_object_set_constructor (Swfdec
   }
   SWFDEC_AS_VALUE_SET_OBJECT (&val, proto);
   swfdec_as_object_set_variable (object, SWFDEC_AS_STR___proto__, &val);
+  swfdec_as_object_set_variable_flags (object, SWFDEC_AS_STR___proto__,
+      SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, construct);
-  swfdec_as_object_set_variable (object, scripted ? SWFDEC_AS_STR_constructor : SWFDEC_AS_STR___constructor__, &val);
+  swfdec_as_object_set_variable (object,
+      scripted ? SWFDEC_AS_STR_constructor : SWFDEC_AS_STR___constructor__,
+      &val);
+  swfdec_as_object_set_variable_flags (object,
+      scripted ? SWFDEC_AS_STR_constructor : SWFDEC_AS_STR___constructor__,
+      SWFDEC_AS_VARIABLE_HIDDEN);
 }
 
 /**
diff-tree a37dad992ab5fe037d4ef153d6a80ee0327262d9 (from 87b80853e78f8281e206db513eb9471b192fffaf)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Aug 17 21:52:19 2007 +0300

    Fix ASSetProbFlags function.

diff --git a/libswfdec/swfdec_as_context.c b/libswfdec/swfdec_as_context.c
index 49ec05e..d0017d0 100644
--- a/libswfdec/swfdec_as_context.c
+++ b/libswfdec/swfdec_as_context.c
@@ -1004,21 +1004,18 @@ swfdec_as_context_eval_set (SwfdecAsCont
 /*** AS CODE ***/
 
 static void
-swfdec_as_context_ASSetPropFlags_set_one_flag (SwfdecAsObject *object, const char *s, guint *flags)
+swfdec_as_context_ASSetPropFlags_set_one_flag (SwfdecAsObject *object,
+    const char *s, guint *flags)
 {
   guint real;
 
-  /* first set all relevant flags */
-  real = flags[0] & flags[1];
-  swfdec_as_object_set_variable_flags (object, s, real);
-  /* then unset all relevant flags */
-  real = ~flags[0] & flags[1];
-  swfdec_as_object_unset_variable_flags (object, s, real);
+  swfdec_as_object_unset_variable_flags (object, s, flags[1]);
+  swfdec_as_object_set_variable_flags (object, s, flags[0]);
 }
 
 static gboolean
-swfdec_as_context_ASSetPropFlags_foreach (SwfdecAsObject *object, const char *s, 
-    SwfdecAsValue *val, guint cur_flags, gpointer data)
+swfdec_as_context_ASSetPropFlags_foreach (SwfdecAsObject *object,
+    const char *s, SwfdecAsValue *val, guint cur_flags, gpointer data)
 {
   guint *flags = data;
 
@@ -1047,16 +1044,15 @@ swfdec_as_context_ASSetPropFlags (Swfdec
   flags[1] = (argc > 3) ? swfdec_as_value_to_integer (cx, &argv[3]) : -1;
   if (SWFDEC_AS_VALUE_IS_NULL (&argv[1])) {
     swfdec_as_object_foreach (obj, swfdec_as_context_ASSetPropFlags_foreach, flags);
-  } else if (SWFDEC_AS_VALUE_IS_STRING (&argv[1])) {
-    char **split = g_strsplit (SWFDEC_AS_VALUE_GET_STRING (&argv[1]), ",", -1);
+  } else {
+    char **split =
+      g_strsplit (swfdec_as_value_to_string (cx, &argv[1]), ",", -1);
     guint i;
     for (i = 0; split[i]; i++) {
       swfdec_as_context_ASSetPropFlags_set_one_flag (obj, 
 	  swfdec_as_context_get_string (cx, split[i]), flags);
     }
     g_strfreev (split); 
-  } else {
-    SWFDEC_FIXME ("ASSetPropFlags for non-null properties not implemented yet");
   }
 }
 
diff-tree 87b80853e78f8281e206db513eb9471b192fffaf (from afdf9987d560b315469d8747f56916dcd3235ecb)
Author: Pekka Lampila <pekka.lampila at iki.fi>
Date:   Fri Aug 17 16:42:12 2007 +0300

    Add test case for propflags. Rename couple of SwfdecAsVariableFlags.
    
    SWFDEC_AS_VARIABLE_NO_ENUM is now SWFDEC_AS_VARIABLE_HIDDEN and
    SWFDEC_AS_VARIABLE_READONLY is now SWFDEC_AS_VARIABLE_CONSTANT

diff --git a/libswfdec/swfdec_as_interpret.c b/libswfdec/swfdec_as_interpret.c
index 47e62d5..f9a2cc2 100644
--- a/libswfdec/swfdec_as_interpret.c
+++ b/libswfdec/swfdec_as_interpret.c
@@ -1870,6 +1870,8 @@ swfdec_action_extends (SwfdecAsContext *
   swfdec_as_object_delete_variable (prototype, SWFDEC_AS_STR_constructor);
   swfdec_as_object_set_variable (prototype, SWFDEC_AS_STR___constructor__,
       superclass);
+  swfdec_as_object_set_variable_flags (prototype, SWFDEC_AS_STR___constructor__,
+      SWFDEC_AS_VARIABLE_HIDDEN);
   SWFDEC_AS_VALUE_SET_OBJECT (&proto, prototype);
   swfdec_as_object_set_variable (SWFDEC_AS_VALUE_GET_OBJECT (subclass),
       SWFDEC_AS_STR_prototype, &proto);
@@ -1883,7 +1885,7 @@ swfdec_action_do_enumerate (SwfdecAsObje
 {
   SwfdecAsContext *cx = cxp;
 
-  if (flags & SWFDEC_AS_VARIABLE_DONT_ENUM)
+  if (flags & SWFDEC_AS_VARIABLE_HIDDEN)
     return TRUE;
   swfdec_as_stack_ensure_free (cx, 1);
   SWFDEC_AS_VALUE_SET_STRING (swfdec_as_stack_push (cx), variable);
diff --git a/libswfdec/swfdec_as_object.c b/libswfdec/swfdec_as_object.c
index b5dcd25..46c590d 100644
--- a/libswfdec/swfdec_as_object.c
+++ b/libswfdec/swfdec_as_object.c
@@ -245,7 +245,7 @@ swfdec_as_object_do_set (SwfdecAsObject 
     if (var == NULL)
       return;
   }
-  if (var->flags & SWFDEC_AS_VARIABLE_READONLY)
+  if (var->flags & SWFDEC_AS_VARIABLE_CONSTANT)
     return;
   if (var->get) {
     if (var->set) {
@@ -773,7 +773,7 @@ swfdec_as_object_add_function (SwfdecAsO
   SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (function));
   /* FIXME: I'd like to make sure no such property exists yet */
   swfdec_as_object_set_variable (object, name, &val);
-  swfdec_as_object_set_variable_flags (object, name, SWFDEC_AS_VARIABLE_DONT_ENUM);
+  swfdec_as_object_set_variable_flags (object, name, SWFDEC_AS_VARIABLE_HIDDEN);
   return function;
 }
 
@@ -993,7 +993,7 @@ swfdec_as_object_add_variable (SwfdecAsO
   var->set = set;
   var->flags = 0;
   if (set == NULL)
-    var->flags |= SWFDEC_AS_VARIABLE_READONLY;
+    var->flags |= SWFDEC_AS_VARIABLE_CONSTANT;
 }
 
 /*** AS CODE ***/
diff --git a/libswfdec/swfdec_as_object.h b/libswfdec/swfdec_as_object.h
index 265c6cb..55bfc05 100644
--- a/libswfdec/swfdec_as_object.h
+++ b/libswfdec/swfdec_as_object.h
@@ -27,9 +27,9 @@ G_BEGIN_DECLS
 
 /* NB: matches ASSetPropFlags */
 typedef enum {
-  SWFDEC_AS_VARIABLE_DONT_ENUM = (1 << 0),
+  SWFDEC_AS_VARIABLE_HIDDEN = (1 << 0),
   SWFDEC_AS_VARIABLE_PERMANENT = (1 << 1),
-  SWFDEC_AS_VARIABLE_READONLY = (1 << 2),
+  SWFDEC_AS_VARIABLE_CONSTANT = (1 << 2),
 
   SWFDEC_AS_VARIABLE_FLASH6_UP = (1 << 7)
 } SwfdecAsVariableFlag;
diff --git a/test/trace/propflags-5.swf b/test/trace/propflags-5.swf
new file mode 100644
index 0000000..b26242b
Binary files /dev/null and b/test/trace/propflags-5.swf differ
diff --git a/test/trace/propflags-5.swf.trace b/test/trace/propflags-5.swf.trace
new file mode 100644
index 0000000..7026d1f
--- /dev/null
+++ b/test/trace/propflags-5.swf.trace
@@ -0,0 +1,3 @@
+Hidden: 7,5,3,1,__constructor__,constructor,__proto__
+Constant: 7,6,5,4
+Permanent: 
diff --git a/test/trace/propflags-6.swf b/test/trace/propflags-6.swf
new file mode 100644
index 0000000..93c2e52
Binary files /dev/null and b/test/trace/propflags-6.swf differ
diff --git a/test/trace/propflags-6.swf.trace b/test/trace/propflags-6.swf.trace
new file mode 100644
index 0000000..a7eb732
--- /dev/null
+++ b/test/trace/propflags-6.swf.trace
@@ -0,0 +1,3 @@
+Hidden: 7,5,3,1,__constructor__,constructor,__proto__
+Constant: 7,6,5,4
+Permanent: 7,6,3,2,__proto__
diff --git a/test/trace/propflags-7.swf b/test/trace/propflags-7.swf
new file mode 100644
index 0000000..9903ec0
Binary files /dev/null and b/test/trace/propflags-7.swf differ
diff --git a/test/trace/propflags-7.swf.trace b/test/trace/propflags-7.swf.trace
new file mode 100644
index 0000000..614873e
--- /dev/null
+++ b/test/trace/propflags-7.swf.trace
@@ -0,0 +1,3 @@
+Hidden: 7,5,3,1,__constructor__,__proto__
+Constant: 7,6,5,4
+Permanent: 7,6,3,2,__proto__
diff --git a/test/trace/propflags.as b/test/trace/propflags.as
new file mode 100644
index 0000000..25ab56b
--- /dev/null
+++ b/test/trace/propflags.as
@@ -0,0 +1,83 @@
+// makeswf -v 7 -r 1 -o test-7.swf test.as
+
+function hidden_properties (obj)
+{
+  normal = new Array ();
+  for (prop in obj) {
+    normal.push (prop);
+  }
+
+  hidden = new Array ();
+  ASSetPropFlags (obj, null, 0, 1);
+  for (prop in obj) {
+    for (i = 0; i < normal.length; i++) {
+      if (normal[i] == prop)
+	break;
+    }
+    if (i == normal.length)
+      hidden.push (prop);
+  }
+  ASSetPropFlags (obj, hidden, 1, 0);
+
+  return hidden;
+}
+
+// loses flags from the properties that are not permanent
+function permanent_properties (obj)
+{
+  hidden = hidden_properties (obj);
+  constant = constant_properties (obj);
+
+  ASSetPropFlags (obj, hidden, 0, 1);
+
+  permanent = new Array();
+  for (var prop in obj) {
+    var old = obj[prop];
+    delete obj[prop];
+    if (obj.hasOwnProperty (prop)) {
+      permanent.push (prop);
+    } else {
+      obj[prop] = old;
+    }
+  }
+
+  ASSetPropFlags (obj, hidden, 1, 0);
+  ASSetPropFlags (obj, constant, 3, 0);
+
+  return permanent;
+}
+
+function constant_properties (obj)
+{
+  hidden = hidden_properties (obj);
+
+  ASSetPropFlags (obj, hidden, 0, 1);
+
+  constant = new Array();
+  for (var prop in obj) {
+    var old = obj[prop];
+    var val = "hello " + obj[prop];
+    obj[prop] = val;
+    if (obj[prop] != val) {
+      constant.push (prop);
+    } else {
+      obj[prop] = old;
+    }
+  }
+
+  ASSetPropFlags (obj, hidden, 1, 0);
+
+  return constant;
+}
+
+var obj = new Object ();
+obj[0] = 0;
+for (var i = 1; i <= 7; i++) {
+  obj[i] = i;
+  ASSetPropFlags (obj, i, i, 0);
+}
+trace ("Hidden: " + hidden_properties (obj));
+trace ("Constant: " + constant_properties (obj));
+trace ("Permanent: " + permanent_properties (obj));
+
+loadMovie ("FSCommand:quit", "");


More information about the Swfdec mailing list