[Swfdec-commits] 20 commits - doc/Makefile.am NEWS swfdec/Makefile.am swfdec/swfdec_as_internal.h swfdec/swfdec_asnative.h swfdec/swfdec_as_string.c swfdec/swfdec_image.c swfdec/swfdec_movie_clip_loader.c swfdec/swfdec_movie_clip_loader.h swfdec/swfdec_player_as.c swfdec/swfdec_player.c swfdec/swfdec_resource.c swfdec/swfdec_text_format.c swfdec/swfdec_text_layout.c swfdec/swfdec_url.c swfdec/swfdec_xml.c swfdec/swfdec_xml_node.c swfdec/swfdec_xml_node.h test/swfdec_test_swfdec_socket.c

Benjamin Otte company at kemper.freedesktop.org
Thu Oct 23 14:35:48 PDT 2008


 NEWS                              |   10 +
 doc/Makefile.am                   |    1 
 swfdec/Makefile.am                |   10 -
 swfdec/swfdec_as_internal.h       |    3 
 swfdec/swfdec_as_string.c         |    7 
 swfdec/swfdec_asnative.h          |    1 
 swfdec/swfdec_image.c             |    3 
 swfdec/swfdec_movie_clip_loader.c |   12 +
 swfdec/swfdec_movie_clip_loader.h |    8 
 swfdec/swfdec_player.c            |    4 
 swfdec/swfdec_player_as.c         |    4 
 swfdec/swfdec_resource.c          |    2 
 swfdec/swfdec_text_format.c       |   13 +
 swfdec/swfdec_text_layout.c       |    1 
 swfdec/swfdec_url.c               |    1 
 swfdec/swfdec_xml.c               |  279 ++++++++++++++------------------
 swfdec/swfdec_xml_node.c          |  331 ++++++++++++++++++++------------------
 swfdec/swfdec_xml_node.h          |    8 
 test/swfdec_test_swfdec_socket.c  |    2 
 19 files changed, 362 insertions(+), 338 deletions(-)

New commits:
commit 89224ed12a7700eb0f40153f8558877a1c2171e4
Merge: 15e5525... b126080...
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 23:33:55 2008 +0200

    Merge branch '0.8'
    
    Conflicts:
    
    	configure.ac
    	swfdec/swfdec_image.c

diff --cc swfdec/swfdec_as_string.c
index 9c3a795,c5f94d4..772140d
--- a/swfdec/swfdec_as_string.c
+++ b/swfdec/swfdec_as_string.c
@@@ -89,15 -106,22 +89,20 @@@ swfdec_as_string_lastIndexOf (SwfdecAsC
    gsize len;
    const char *s;
  
 -  if (argc < 1)
 -    return;
 +  SWFDEC_AS_STRING_CHECK (&string, "s", &s);
  
 -  s = swfdec_as_value_to_string (cx, &argv[0]);
    if (argc == 2) {
      int offset = swfdec_as_value_to_integer (cx, &argv[1]);
+     const char *tmp;
      if (offset < 0) {
 -      SWFDEC_AS_VALUE_SET_INT (ret, -1);
 +      swfdec_as_value_set_integer (cx, ret, -1);
        return;
      }
-     len = g_utf8_offset_to_pointer (string, offset + 1) - string;
+     tmp = string;
+     offset++;
+     while (*tmp && offset-- != 0)
+       tmp = g_utf8_next_char (tmp);
+     len = tmp - string;
    } else {
      len = G_MAXSIZE;
    }
diff --cc swfdec/swfdec_image.c
index 8e13550,23a6845..3afc940
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@@ -694,11 -693,8 +694,11 @@@ swfdec_image_create_surface_transforme
      }
    }
  
 -  surface = swfdec_renderer_transform (renderer, source, trans);
 +  area.x = area.y = 0;
 +  area.width = image->width;
 +  area.height = image->height;
 +  surface = swfdec_renderer_transform (renderer, source, trans, &area);
- 
+   cairo_surface_destroy (source);
    if (renderer) {
      surface = swfdec_renderer_create_similar (renderer, surface);
      /* FIXME: The size is just an educated guess */
commit b1260803099cad927089e9deada1754b995d85a3
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 23:24:14 2008 +0200

    back to development

diff --git a/configure.ac b/configure.ac
index e2eb3b3..20e04e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ([2.58])
 
 m4_define(swfdec_major, 0)
 m4_define(swfdec_minor, 8)
-m4_define(swfdec_micro, 2)
+m4_define(swfdec_micro, 3)
 AC_INIT(swfdec,[swfdec_major.swfdec_minor.swfdec_micro])
 
 SWFDEC_VERSION_MAJOR=swfdec_major
commit 8ea44f09d008d1faed954428a5f608be36cfc61d
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 23:23:39 2008 +0200

    release 0.8.2

diff --git a/configure.ac b/configure.ac
index 81d00d6..e2eb3b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ AC_PREREQ([2.58])
 
 m4_define(swfdec_major, 0)
 m4_define(swfdec_minor, 8)
-m4_define(swfdec_micro, 1)
+m4_define(swfdec_micro, 2)
 AC_INIT(swfdec,[swfdec_major.swfdec_minor.swfdec_micro])
 
 SWFDEC_VERSION_MAJOR=swfdec_major
commit a9cab7b3d628d812bdc8ed4727931103ad9af661
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 23:10:36 2008 +0200

    update NEWS

diff --git a/NEWS b/NEWS
index bbad1ae..7c39d8b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,14 @@
 
+ 0.8.2 ("Gametrailers")
+
+Here's the first stable release.
+- fix crash when reading invalid JPEG images
+- fix invalid memory accesses
+- fix deadlock when sound stream had no data
+- fix regression where some files weren't loaded.
+- lots of memory leaks plugged
+- various build fixes/improvements
+
  0.8.0 ("Slide")
 
 And here is our 6monthly stable release again:
commit 3cb78d1e54d95d70cb18c4cd90933c51770f36f2
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 22:21:53 2008 +0200

    build fix for docs when srcdir != builddir

diff --git a/doc/Makefile.am b/doc/Makefile.am
index 50b2197..4e9a69f 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -174,6 +174,7 @@ IGNORE_HFILES= \
 
 if WITH_GTK
 EXTRA_HFILES = \
+	../swfdec/swfdec_version.h.in \
 	../swfdec-gtk/swfdec_gtk_keys.h \
 	../swfdec-gtk/swfdec_gtk_loader.h \
 	../swfdec-gtk/swfdec_gtk_player.h \
commit 7fafbe5fa68968b93733406a0c3b5075df57b130
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 22 12:10:03 2008 +0200

    rename variable to avoid shadowing

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 505af2d..2d89527 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -1114,8 +1114,8 @@ swfdec_player_dispose (GObject *object)
 }
 
 static void
-swfdec_player_broadcast (SwfdecPlayer *player, const char *object_name, const char *signal,
-    guint argc, SwfdecAsValue *argv)
+swfdec_player_broadcast (SwfdecPlayer *player, const char *object_name, 
+    const char *signal_name, guint argc, SwfdecAsValue *argv)
 {
   GSList *walk;
   SwfdecAsValue vals[3];
@@ -1128,7 +1128,7 @@ swfdec_player_broadcast (SwfdecPlayer *player, const char *object_name, const ch
     memcpy (&vals[1], argv, argc * sizeof (SwfdecAsValue));
   }
 
-  SWFDEC_DEBUG ("broadcasting message %s.%s", object_name, signal);
+  SWFDEC_DEBUG ("broadcasting message %s.%s", object_name, signal_name);
   /* FIXME: sandbox ordering? */
   for (walk = player->priv->sandboxes; walk; walk = walk->next) {
     SwfdecSandbox *sandbox = walk->data;
@@ -1136,7 +1136,7 @@ swfdec_player_broadcast (SwfdecPlayer *player, const char *object_name, const ch
     if (!SWFDEC_AS_VALUE_IS_OBJECT (&vals[0]))
       return;
     obj = SWFDEC_AS_VALUE_GET_OBJECT (&vals[0]);
-    SWFDEC_AS_VALUE_SET_STRING (&vals[0], signal);
+    SWFDEC_AS_VALUE_SET_STRING (&vals[0], signal_name);
     swfdec_sandbox_use (sandbox);
     swfdec_as_object_call (obj, SWFDEC_AS_STR_broadcastMessage, argc + 1, vals, NULL);
     swfdec_sandbox_unuse (sandbox);
commit f4a39bd4cb8b55c4def1f219b3e607e53f412236
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 22:10:57 2008 +0200

    fix memleak in test code

diff --git a/test/swfdec_test_swfdec_socket.c b/test/swfdec_test_swfdec_socket.c
index 4cc887f..bdcacd3 100644
--- a/test/swfdec_test_swfdec_socket.c
+++ b/test/swfdec_test_swfdec_socket.c
@@ -36,6 +36,8 @@ swfdec_test_swfdec_socket_close (SwfdecStream *stream)
   SwfdecTestSwfdecSocket *test = SWFDEC_TEST_SWFDEC_SOCKET (stream);
 
   test->plugin.close (&test->plugin);
+  g_free (test->plugin.host);
+  test->plugin.host = NULL;
 }
 
 static void
commit e301d5bc0fd24e5a5de56f06b88deeac707bd202
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 22:10:42 2008 +0200

    fix memleak when tab stops are set

diff --git a/swfdec/swfdec_text_format.c b/swfdec/swfdec_text_format.c
index 7442a0d..05f522e 100644
--- a/swfdec/swfdec_text_format.c
+++ b/swfdec/swfdec_text_format.c
@@ -74,10 +74,23 @@ swfdec_text_format_mark (SwfdecGcObject *object)
 }
 
 static void
+swfdec_text_format_dispose (GObject *object)
+{
+  SwfdecTextFormat *format = SWFDEC_TEXT_FORMAT (object);
+
+  swfdec_text_attributes_reset (&format->attr);
+
+  G_OBJECT_CLASS (swfdec_text_format_parent_class)->dispose (object);
+}
+
+static void
 swfdec_text_format_class_init (SwfdecTextFormatClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   SwfdecGcObjectClass *gc_class = SWFDEC_GC_OBJECT_CLASS (klass);
 
+  object_class->dispose = swfdec_text_format_dispose;
+
   gc_class->mark = swfdec_text_format_mark;
 }
 
commit ad49f2a90401d47877d4246df8f51d81a5f3084c
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 22:09:52 2008 +0200

    fix lastIndexOf potentially reading invalid memory
    
    g_utf8_offset_to_pointer() requires a valid offset

diff --git a/swfdec/swfdec_as_string.c b/swfdec/swfdec_as_string.c
index e9ba518..c5f94d4 100644
--- a/swfdec/swfdec_as_string.c
+++ b/swfdec/swfdec_as_string.c
@@ -112,11 +112,16 @@ swfdec_as_string_lastIndexOf (SwfdecAsContext *cx, SwfdecAsObject *object,
   s = swfdec_as_value_to_string (cx, &argv[0]);
   if (argc == 2) {
     int offset = swfdec_as_value_to_integer (cx, &argv[1]);
+    const char *tmp;
     if (offset < 0) {
       SWFDEC_AS_VALUE_SET_INT (ret, -1);
       return;
     }
-    len = g_utf8_offset_to_pointer (string, offset + 1) - string;
+    tmp = string;
+    offset++;
+    while (*tmp && offset-- != 0)
+      tmp = g_utf8_next_char (tmp);
+    len = tmp - string;
   } else {
     len = G_MAXSIZE;
   }
commit 680e77e39af08b7066c471550633cb362f201924
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:44:10 2008 +0200

    don't leak the original image when transforming it

diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index 7c455af..23a6845 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -694,6 +694,7 @@ swfdec_image_create_surface_transformed (SwfdecImage *image, SwfdecRenderer *ren
   }
 
   surface = swfdec_renderer_transform (renderer, source, trans);
+  cairo_surface_destroy (source);
   if (renderer) {
     surface = swfdec_renderer_create_similar (renderer, surface);
     /* FIXME: The size is just an educated guess */
commit 4f0f72df163df9a3fc00e627fe83051b92a44a73
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:18:23 2008 +0200

    don't leak the attribute iterator

diff --git a/swfdec/swfdec_text_layout.c b/swfdec/swfdec_text_layout.c
index c5fd4cf..0653499 100644
--- a/swfdec/swfdec_text_layout.c
+++ b/swfdec/swfdec_text_layout.c
@@ -900,6 +900,7 @@ swfdec_text_layout_modify_attributes (SwfdecTextLayout *layout,
   } while (pango_attr_iterator_next (iter));
   pango_layout_set_attributes (block->layout, new);
   pango_attr_list_unref (new);
+  pango_attr_iterator_destroy (iter);
   return old;
 }
 
commit b64d8ee225ebb6803c96cdee77df5e7663935f2d
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:18:08 2008 +0200

    don't leak the escaped text

diff --git a/swfdec/swfdec_url.c b/swfdec/swfdec_url.c
index b2b7d0a..40af41a 100644
--- a/swfdec/swfdec_url.c
+++ b/swfdec/swfdec_url.c
@@ -682,6 +682,7 @@ swfdec_url_new_from_input (const char *input)
     char *escaped =
       g_uri_escape_string (input[0] == '/' ? &input[1] : &input[0], "/", TRUE);
     url = swfdec_url_new_components ("file", NULL, 0, escaped, NULL);
+    g_free (escaped);
   } else {
     char *absolute, *cur;
     cur = g_get_current_dir ();
commit 3c03ca3f860980f187a5879126ab98979edc5a07
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:17:43 2008 +0200

    fix rather huge memleak of the renderer in every SwfdecPlayer

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index 6515189..505af2d 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -1093,6 +1093,10 @@ swfdec_player_dispose (GObject *object)
   }
   g_array_free (priv->invalidations, TRUE);
   priv->invalidations = NULL;
+  if (priv->renderer) {
+    g_object_unref (priv->renderer);
+    priv->renderer = NULL;
+  }
   if (priv->runtime) {
     g_timer_destroy (priv->runtime);
     priv->runtime = NULL;
commit cea4227c1502f1abda9125b1793dc997dec5e4bc
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:17:27 2008 +0200

    fix memleak when loading lossless images

diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index 92bef53..7c455af 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -469,6 +469,7 @@ swfdec_image_lossless_load (SwfdecImage *image, SwfdecRenderer *renderer)
       }
     }
     data = g_memdup (buffer->data, buffer->length);
+    swfdec_buffer_unref (buffer);
   } else {
     SWFDEC_ERROR ("unknown lossless image format %u", format);
     return NULL;
commit 15e5525d52def6d616e8d81e56c8873d1f78ae5f
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:18:23 2008 +0200

    don't leak the attribute iterator

diff --git a/swfdec/swfdec_text_layout.c b/swfdec/swfdec_text_layout.c
index c5fd4cf..0653499 100644
--- a/swfdec/swfdec_text_layout.c
+++ b/swfdec/swfdec_text_layout.c
@@ -900,6 +900,7 @@ swfdec_text_layout_modify_attributes (SwfdecTextLayout *layout,
   } while (pango_attr_iterator_next (iter));
   pango_layout_set_attributes (block->layout, new);
   pango_attr_list_unref (new);
+  pango_attr_iterator_destroy (iter);
   return old;
 }
 
commit 2befe27526377de64fda740dadb228f96aba7269
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:18:08 2008 +0200

    don't leak the escaped text

diff --git a/swfdec/swfdec_url.c b/swfdec/swfdec_url.c
index b2b7d0a..40af41a 100644
--- a/swfdec/swfdec_url.c
+++ b/swfdec/swfdec_url.c
@@ -682,6 +682,7 @@ swfdec_url_new_from_input (const char *input)
     char *escaped =
       g_uri_escape_string (input[0] == '/' ? &input[1] : &input[0], "/", TRUE);
     url = swfdec_url_new_components ("file", NULL, 0, escaped, NULL);
+    g_free (escaped);
   } else {
     char *absolute, *cur;
     cur = g_get_current_dir ();
commit df50c8919de79ab0944fd08aee70d288e9703513
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:17:43 2008 +0200

    fix rather huge memleak of the renderer in every SwfdecPlayer

diff --git a/swfdec/swfdec_player.c b/swfdec/swfdec_player.c
index a63d1e6..9cbe483 100644
--- a/swfdec/swfdec_player.c
+++ b/swfdec/swfdec_player.c
@@ -1094,6 +1094,10 @@ swfdec_player_dispose (GObject *object)
   }
   g_array_free (priv->invalidations, TRUE);
   priv->invalidations = NULL;
+  if (priv->renderer) {
+    g_object_unref (priv->renderer);
+    priv->renderer = NULL;
+  }
   if (priv->runtime) {
     g_timer_destroy (priv->runtime);
     priv->runtime = NULL;
commit 3c7838c01eece6d33c51d6897f52ab829632841f
Author: Benjamin Otte <otte at gnome.org>
Date:   Thu Oct 23 13:17:27 2008 +0200

    fix memleak when loading lossless images

diff --git a/swfdec/swfdec_image.c b/swfdec/swfdec_image.c
index 65890ad..8e13550 100644
--- a/swfdec/swfdec_image.c
+++ b/swfdec/swfdec_image.c
@@ -469,6 +469,7 @@ swfdec_image_lossless_load (SwfdecImage *image, SwfdecRenderer *renderer)
       }
     }
     data = g_memdup (buffer->data, buffer->length);
+    swfdec_buffer_unref (buffer);
   } else {
     SWFDEC_ERROR ("unknown lossless image format %u", format);
     return NULL;
commit 3739e1241048af0289321cc86c25f92c96b5c45b
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 22 18:22:31 2008 +0200

    make XML and XMLNode relays
    
    also remove the now dead SWFDEC_AS_CONSTRUCTOR code

diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 0f2084d..dfdce00 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -381,19 +381,13 @@ swfdec_asnative.c: $(libswfdec_source_files)
 	  && echo "#include \"swfdec_as_types.h\"" \
 	  && echo "#define SWFDEC_AS_NATIVE(x,y,func) void func (SwfdecAsContext *cx, \\" \
 	  && echo "    SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);" \
-	  && echo "#define SWFDEC_AS_CONSTRUCTOR(x,y,func,type) SWFDEC_AS_NATIVE(x,y,func) GType type (void);" \
-	  && grep -he "^SWFDEC_AS_CONSTRUCTOR" $(libswfdec_source_files) \
 	  && grep -he "^SWFDEC_AS_NATIVE" $(libswfdec_source_files) \
-	  && echo "#undef SWFDEC_AS_CONSTRUCTOR" \
 	  && echo "#undef SWFDEC_AS_NATIVE" \
-	  && echo "#define SWFDEC_AS_NATIVE(x,y,func) SWFDEC_AS_CONSTRUCTOR(x,y,func,NULL)" \
-	  && echo "#define SWFDEC_AS_CONSTRUCTOR(x,y,func,type) { x, y, func, G_STRINGIFY (func), type }," \
-	  && echo "const struct { guint x, y; SwfdecAsNative func; const char *name; GType (* get_type) (void); } native_funcs[] = {" \
-	  && grep -he "^SWFDEC_AS_CONSTRUCTOR" $(libswfdec_source_files) \
+	  && echo "#define SWFDEC_AS_NATIVE(x,y,func) { x, y, func, G_STRINGIFY (func) }," \
+	  && echo "const struct { guint x, y; SwfdecAsNative func; const char *name; } native_funcs[] = {" \
 	  && grep -he "^SWFDEC_AS_NATIVE" $(libswfdec_source_files) \
 	  && echo "  { 0, 0, NULL }" \
 	  && echo "};" \
-	  && echo "#undef SWFDEC_AS_CONSTRUCTOR" \
 	  && echo "#undef SWFDEC_AS_NATIVE" \
 	 ) >> xgen-san \
 	&& (cmp -s xgen-san swfdec_asnative.c || cp xgen-san swfdec_asnative.c) \
diff --git a/swfdec/swfdec_as_internal.h b/swfdec/swfdec_as_internal.h
index ad79b87..4b53c46 100644
--- a/swfdec/swfdec_as_internal.h
+++ b/swfdec/swfdec_as_internal.h
@@ -29,8 +29,7 @@ G_BEGIN_DECLS
 /* This header contains all the non-exported symbols that can't go into 
  * exported headers 
  */
-#define SWFDEC_AS_NATIVE(x, y, func) SWFDEC_AS_CONSTRUCTOR (x, y, func, NULL)
-#define SWFDEC_AS_CONSTRUCTOR(x, y, func, type) void func (SwfdecAsContext *cx, \
+#define SWFDEC_AS_NATIVE(x, y, func) void func (SwfdecAsContext *cx, \
     SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret);
 
 #define SWFDEC_AS_OBJECT_PROTOTYPE_RECURSION_LIMIT 256
diff --git a/swfdec/swfdec_asnative.h b/swfdec/swfdec_asnative.h
index e512bb6..ab42f6e 100644
--- a/swfdec/swfdec_asnative.h
+++ b/swfdec/swfdec_asnative.h
@@ -28,7 +28,6 @@ extern const struct {
   guint x, y; 
   SwfdecAsNative func; 
   const char *name; 
-  GType (* get_type) (void); 
 } native_funcs[];
 
 G_END_DECLS
diff --git a/swfdec/swfdec_player_as.c b/swfdec/swfdec_player_as.c
index 0845931..0809ac9 100644
--- a/swfdec/swfdec_player_as.c
+++ b/swfdec/swfdec_player_as.c
@@ -172,10 +172,6 @@ swfdec_get_asnative (SwfdecAsContext *cx, guint x, guint y)
     if (native_funcs[i].x == x && native_funcs[i].y == y) {
       SwfdecAsFunction *fun = swfdec_as_native_function_new (cx, native_funcs[i].name,
 	  native_funcs[i].func, NULL);
-      if (native_funcs[i].get_type) {
-	swfdec_as_native_function_set_construct_type (SWFDEC_AS_NATIVE_FUNCTION (fun),
-	    native_funcs[i].get_type ());
-      }
       return fun;
     }
   }
diff --git a/swfdec/swfdec_xml.c b/swfdec/swfdec_xml.c
index 4ca7be5..f5503a6 100644
--- a/swfdec/swfdec_xml.c
+++ b/swfdec/swfdec_xml.c
@@ -1,5 +1,5 @@
 /* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2007-2008 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
@@ -48,6 +48,9 @@ swfdec_xml_mark (SwfdecGcObject *object)
   if (xml->doc_type_decl != NULL)
     swfdec_as_string_mark (xml->doc_type_decl);
 
+  swfdec_as_value_mark (&xml->content_type);
+  swfdec_as_value_mark (&xml->loaded);
+
   SWFDEC_GC_OBJECT_CLASS (swfdec_xml_parent_class)->mark (object);
 }
 
@@ -62,6 +65,8 @@ swfdec_xml_class_init (SwfdecXmlClass *klass)
 static void
 swfdec_xml_init (SwfdecXml *xml)
 {
+  SWFDEC_AS_VALUE_SET_STRING (&xml->content_type,
+      SWFDEC_AS_STR_application_x_www_form_urlencoded);
 }
 
 typedef struct {
@@ -170,12 +175,12 @@ void
 swfdec_xml_do_escape (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
+  const char *s;
   char *escaped;
 
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (0, NULL, "s", &s);
 
-  escaped = swfdec_xml_escape (swfdec_as_value_to_string (cx, &argv[0]));
+  escaped = swfdec_xml_escape (s);
   SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_as_context_give_string (cx, escaped));
 }
 
@@ -183,31 +188,27 @@ static void
 swfdec_xml_get_ignoreWhite (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "");
 
-  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, SWFDEC_XML (object)->ignore_white);
+  SWFDEC_AS_VALUE_SET_BOOLEAN (ret, xml->ignore_white);
 }
 
 static void
 swfdec_xml_set_ignoreWhite (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
+  char *ignore;
 
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &ignore);
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  // special case, call toString of objects
-  if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]))
-    swfdec_as_value_to_string (cx, &argv[0]);
-
-  SWFDEC_XML (object)->ignore_white =
+  xml->ignore_white =
     swfdec_as_value_to_boolean (cx, &argv[0]);
 }
 
@@ -215,11 +216,12 @@ static void
 swfdec_xml_get_xmlDecl (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
 
-  if (SWFDEC_XML (object)->xml_decl != NULL) {
-    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_XML (object)->xml_decl);
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "");
+
+  if (xml->xml_decl != NULL) {
+    SWFDEC_AS_VALUE_SET_STRING (ret, xml->xml_decl);
   } else {
     SWFDEC_AS_VALUE_SET_UNDEFINED (ret);
   }
@@ -229,28 +231,28 @@ static void
 swfdec_xml_set_xmlDecl (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
+  const char *s;
 
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &s);
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  SWFDEC_XML (object)->xml_decl = swfdec_as_value_to_string (cx, &argv[0]);
+  xml->xml_decl = s;
 }
 
 static void
 swfdec_xml_get_docTypeDecl (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "");
 
-  if (SWFDEC_XML (object)->doc_type_decl != NULL) {
-    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_XML (object)->doc_type_decl);
+  if (xml->doc_type_decl != NULL) {
+    SWFDEC_AS_VALUE_SET_STRING (ret, xml->doc_type_decl);
   } else {
     SWFDEC_AS_VALUE_SET_UNDEFINED (ret);
   }
@@ -260,76 +262,70 @@ static void
 swfdec_xml_set_docTypeDecl (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
+  const char *s;
 
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &s);
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  SWFDEC_XML (object)->doc_type_decl =
-    swfdec_as_value_to_string (cx, &argv[0]);
+  xml->doc_type_decl = s;
 }
 
 static void
 swfdec_xml_get_contentType (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
 
-  *ret = SWFDEC_XML (object)->content_type;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "");
+
+  *ret = xml->content_type;
 }
 
 static void
 swfdec_xml_set_contentType (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
+  SwfdecAsValue val;
 
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "v", &val);
 
   // special case
-  if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
+  if (SWFDEC_AS_VALUE_IS_UNDEFINED (&val))
     return;
 
-  SWFDEC_XML (object)->content_type = argv[0];
+  xml->content_type = val;
 }
 
 static void
 swfdec_xml_get_loaded (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
 
-  *ret = SWFDEC_XML (object)->loaded;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "");
+
+  *ret = xml->loaded;
 }
 
 static void
 swfdec_xml_set_loaded (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
-
-  if (argc < 1)
-    return;
+  SwfdecXml *xml;
+  const char *ignore;
 
-  // special case, call toString of objects
-  if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]))
-    swfdec_as_value_to_string (cx, &argv[0]);
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &ignore);
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  SWFDEC_AS_VALUE_SET_BOOLEAN (&SWFDEC_XML (object)->loaded,
+  SWFDEC_AS_VALUE_SET_BOOLEAN (&xml->loaded,
       swfdec_as_value_to_boolean (cx, &argv[0]));
 }
 
@@ -337,10 +333,11 @@ static void
 swfdec_xml_get_status (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
+  SwfdecXml *xml;
 
-  swfdec_as_value_set_integer (cx, ret, SWFDEC_XML (object)->status);
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "");
+
+  swfdec_as_value_set_integer (cx, ret, xml->status);
 }
 
 static void
@@ -348,23 +345,20 @@ swfdec_xml_set_status (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   double d;
+  SwfdecXml *xml;
+  const char *ignore;
 
-  if (!SWFDEC_IS_XML (object))
-    return;
-
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &ignore);
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  swfdec_as_value_to_string (cx, &argv[0]);
   d = swfdec_as_value_to_number (cx, &argv[0]);
   if (!isfinite (d))
-    SWFDEC_XML (object)->status = 0;
+    xml->status = 0;
   else
-    SWFDEC_XML (object)->status = d;
+    xml->status = d;
 }
 
 static const char *
@@ -472,14 +466,17 @@ static void
 swfdec_xml_add_id_map (SwfdecXml *xml, SwfdecXmlNode *node, const char *id)
 {
   SwfdecAsObject *object;
+  SwfdecAsContext *context;
   SwfdecAsValue val;
 
   g_return_if_fail (SWFDEC_IS_XML (xml));
   g_return_if_fail (SWFDEC_IS_XML_NODE (xml));
   g_return_if_fail (id != NULL && id != SWFDEC_AS_STR_EMPTY);
 
-  if (swfdec_gc_object_get_context (xml)->version >= 8) {
-    if (swfdec_as_object_get_variable (SWFDEC_AS_OBJECT (xml),
+  context = swfdec_gc_object_get_context (xml);
+  object = swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml));
+  if (context->version >= 8) {
+    if (swfdec_as_object_get_variable (object,
 	  SWFDEC_AS_STR_idMap, &val)) {
       if (SWFDEC_AS_VALUE_IS_OBJECT (&val)) {
 	object = SWFDEC_AS_VALUE_GET_OBJECT (&val);
@@ -487,22 +484,21 @@ swfdec_xml_add_id_map (SwfdecXml *xml, SwfdecXmlNode *node, const char *id)
 	return;
       }
     } else {
-      object = swfdec_as_object_new_empty (swfdec_gc_object_get_context (xml));
+      object = swfdec_as_object_new_empty (context);
       SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
-      swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (xml),
+      swfdec_as_object_set_variable (swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml)),
 	  SWFDEC_AS_STR_idMap, &val);
     }
-  } else {
-    object = SWFDEC_AS_OBJECT (xml);
   }
 
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (node));
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node)));
   swfdec_as_object_set_variable (object, id, &val);
 }
 
 static const char *
 swfdec_xml_parse_attribute (SwfdecXml *xml, SwfdecXmlNode *node, const char *p)
 {
+  SwfdecAsContext *cx;
   SwfdecAsValue val;
   const char *end, *name;
   char *text;
@@ -517,9 +513,9 @@ swfdec_xml_parse_attribute (SwfdecXml *xml, SwfdecXmlNode *node, const char *p)
     return strchr (p, '\0');
   }
 
+  cx = swfdec_gc_object_get_context (node);
   text = g_strndup (p, end - p);
-  name = swfdec_as_context_give_string (swfdec_gc_object_get_context (node),
-      swfdec_xml_unescape (swfdec_gc_object_get_context (xml), text));
+  name = swfdec_as_context_give_string (cx, swfdec_xml_unescape (cx, text));
   g_free (text);
 
   p = end + strspn (end, " \r\n\t");
@@ -548,10 +544,8 @@ swfdec_xml_parse_attribute (SwfdecXml *xml, SwfdecXmlNode *node, const char *p)
     char *unescaped;
     const char *value;
 
-    unescaped = swfdec_xml_unescape_len (swfdec_gc_object_get_context (xml),
-	p + 1, end - (p + 1), TRUE);
-    value = swfdec_as_context_give_string (swfdec_gc_object_get_context (node),
-	unescaped);
+    unescaped = swfdec_xml_unescape_len (cx, p + 1, end - (p + 1), TRUE);
+    value = swfdec_as_context_give_string (cx, unescaped);
     SWFDEC_AS_VALUE_SET_STRING (&val, value);
 
     swfdec_as_object_set_variable (node->attributes, name, &val);
@@ -566,7 +560,8 @@ static const char *
 swfdec_xml_parse_tag (SwfdecXml *xml, SwfdecXmlNode **node, const char *p)
 {
   SwfdecAsObject *object;
-  SwfdecXmlNode *child = NULL; // surpress warning
+  SwfdecAsContext *cx;
+  SwfdecXmlNode *child = NULL; // supress warning
   char *name;
   const char *end;
   gboolean close;
@@ -575,7 +570,8 @@ swfdec_xml_parse_tag (SwfdecXml *xml, SwfdecXmlNode **node, const char *p)
   g_return_val_if_fail (*p == '<', strchr (p, '\0'));
   g_return_val_if_fail (SWFDEC_IS_XML (xml), strchr (p, '\0'));
 
-  object = SWFDEC_AS_OBJECT (xml);
+  object = swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml));
+  cx = swfdec_gc_object_get_context (xml);
 
   // closing tag or opening tag?
   if (*(p + 1) == '/') {
@@ -600,21 +596,14 @@ swfdec_xml_parse_tag (SwfdecXml *xml, SwfdecXmlNode **node, const char *p)
 
   name = g_strndup (p + 1 , end - (p + 1));
 
-  // create the new element
-  if (!close) {
-    child = swfdec_xml_node_new_no_properties (
-	swfdec_gc_object_get_context (*node), SWFDEC_XML_NODE_ELEMENT,
-	swfdec_as_context_give_string (swfdec_gc_object_get_context (*node),
-	  name));
-    if (child == NULL)
-      return strchr (p, '\0');
-  }
-
   if (close) {
     end = strchr (end, '>');
     if (end == NULL)
       end = strchr (p, '\0');
   } else {
+    // create the new element
+    child = swfdec_xml_node_new_no_properties (cx, SWFDEC_XML_NODE_ELEMENT,
+	swfdec_as_context_give_string (cx, name));
     end = end + strspn (end, " \r\n\t");
     while (*end != '\0' && *end != '>' && (*end != '/' || *(end + 1) != '>')) {
       end = swfdec_xml_parse_attribute (xml, child, end);
@@ -633,12 +622,10 @@ swfdec_xml_parse_tag (SwfdecXml *xml, SwfdecXmlNode **node, const char *p)
   }
 
   if (close) {
-    if ((*node)->parent != NULL && !g_ascii_strcasecmp ((*node)->name, name))
-    {
+    if ((*node)->parent != NULL && !g_ascii_strcasecmp ((*node)->name, name)) {
       *node = (*node)->parent;
-    }
-    else // error
-    {
+    } else {
+      /* error */
       SwfdecXmlNode *iter = *node;
       while (iter != NULL && (iter->name == NULL || g_ascii_strcasecmp (iter->name, name))) {
 	iter = iter->parent;
@@ -673,6 +660,7 @@ swfdec_xml_parse_tag (SwfdecXml *xml, SwfdecXmlNode **node, const char *p)
 static const char *
 swfdec_xml_parse_cdata (SwfdecXml *xml, SwfdecXmlNode *node, const char *p)
 {
+  SwfdecAsContext *cx;
   SwfdecXmlNode *child;
   const char *end;
   char *text;
@@ -693,11 +681,9 @@ swfdec_xml_parse_cdata (SwfdecXml *xml, SwfdecXmlNode *node, const char *p)
 
   text = g_strndup (p, end - p);
 
-  child = swfdec_xml_node_new_no_properties (
-      swfdec_gc_object_get_context (node), SWFDEC_XML_NODE_TEXT,
-      swfdec_as_context_give_string (swfdec_gc_object_get_context (xml), text));
-  if (child == NULL)
-    return strchr (p, '\0');
+  cx = swfdec_gc_object_get_context (xml);
+  child = swfdec_xml_node_new_no_properties (cx, SWFDEC_XML_NODE_TEXT,
+      swfdec_as_context_give_string (cx, text));
   swfdec_xml_node_appendChild (node, child);
 
   end += strlen("]]>");
@@ -725,15 +711,12 @@ swfdec_xml_parse_text (SwfdecXml *xml, SwfdecXmlNode *node,
 
   if (!ignore_white || strspn (p, " \t\r\n") < (gsize)(end - p))
   {
+    SwfdecAsContext *cx = swfdec_gc_object_get_context (xml);
     text = g_strndup (p, end - p);
-    unescaped = swfdec_xml_unescape (swfdec_gc_object_get_context (xml), text);
+    unescaped = swfdec_xml_unescape (cx, text);
     g_free (text);
-    child = swfdec_xml_node_new_no_properties (
-	swfdec_gc_object_get_context (node), SWFDEC_XML_NODE_TEXT,
-	swfdec_as_context_give_string (swfdec_gc_object_get_context (xml),
-	  unescaped));
-    if (child == NULL)
-      return strchr (p, '\0');
+    child = swfdec_xml_node_new_no_properties (cx, SWFDEC_XML_NODE_TEXT,
+	swfdec_as_context_give_string (cx, unescaped));
     swfdec_xml_node_appendChild (node, child);
   }
 
@@ -753,7 +736,8 @@ swfdec_xml_parseXML (SwfdecXml *xml, const char *value)
   g_return_if_fail (SWFDEC_IS_XML (xml));
   g_return_if_fail (value != NULL);
 
-  object = SWFDEC_AS_OBJECT (xml);
+  object = swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (xml));
+  node = SWFDEC_XML_NODE (xml);
 
   swfdec_xml_node_removeChildren (SWFDEC_XML_NODE (xml));
   xml->xml_decl = NULL;
@@ -761,7 +745,6 @@ swfdec_xml_parseXML (SwfdecXml *xml, const char *value)
   xml->status = XML_PARSE_STATUS_OK;
 
   p = value;
-  node = SWFDEC_XML_NODE (xml);
 
   // special case: we only use the ignoreWhite set at the start
   ignore_white = xml->ignore_white;
@@ -804,20 +787,15 @@ void
 swfdec_xml_do_parseXML (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
     SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
-  if (!SWFDEC_IS_XML (object))
-    return;
-
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
-    return;
+  SwfdecXml *xml;
+  const char *s;
 
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &s);
 
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  swfdec_xml_parseXML (SWFDEC_XML (object),
-      swfdec_as_value_to_string (cx, &argv[0]));
+  swfdec_xml_parseXML (xml, s);
 }
 
 SWFDEC_AS_NATIVE (253, 10, swfdec_xml_createElement)
@@ -826,23 +804,18 @@ swfdec_xml_createElement (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
   SwfdecXmlNode *node;
+  SwfdecXml *xml;
+  const char *s;
 
-  if (!SWFDEC_IS_XML (object))
-    return;
-
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &s);
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  node = swfdec_xml_node_new (cx, SWFDEC_XML_NODE_ELEMENT,
-      swfdec_as_value_to_string (cx, &argv[0]));
-  if (node == NULL)
-    return;
+  node = swfdec_xml_node_new (cx, SWFDEC_XML_NODE_ELEMENT, s);
 
-  SWFDEC_AS_VALUE_SET_OBJECT (rval, SWFDEC_AS_OBJECT (node));
+  SWFDEC_AS_VALUE_SET_OBJECT (rval, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node)));
 }
 
 SWFDEC_AS_NATIVE (253, 11, swfdec_xml_createTextNode)
@@ -851,23 +824,18 @@ swfdec_xml_createTextNode (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
 {
   SwfdecXmlNode *node;
+  SwfdecXml *xml;
+  const char *s;
 
-  if (!SWFDEC_IS_XML (object))
-    return;
-
-  if (argc < 1)
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML, &xml, "s", &s);
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  node = swfdec_xml_node_new (cx, SWFDEC_XML_NODE_TEXT,
-      swfdec_as_value_to_string (cx, &argv[0]));
-  if (node == NULL)
-    return;
+  node = swfdec_xml_node_new (cx, SWFDEC_XML_NODE_TEXT, s);
 
-  SWFDEC_AS_VALUE_SET_OBJECT (rval, SWFDEC_AS_OBJECT (node));
+  SWFDEC_AS_VALUE_SET_OBJECT (rval, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node)));
 }
 
 static void
@@ -907,31 +875,29 @@ swfdec_xml_init_properties (SwfdecAsContext *cx)
       swfdec_xml_get_loaded, swfdec_xml_set_loaded);
 }
 
-SWFDEC_AS_CONSTRUCTOR (253, 9, swfdec_xml_construct, swfdec_xml_get_type)
+SWFDEC_AS_NATIVE (253, 9, swfdec_xml_construct)
 void
 swfdec_xml_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
+  SwfdecXml *xml;
+
   if (!swfdec_as_context_is_constructing (cx))
     return;
 
-  g_assert (SWFDEC_IS_XML (object));
-
   swfdec_xml_init_properties (cx);
 
-  swfdec_xml_node_init_values (SWFDEC_XML_NODE (object),
-      SWFDEC_XML_NODE_ELEMENT, SWFDEC_AS_STR_EMPTY);
-
-  SWFDEC_AS_VALUE_SET_STRING (&SWFDEC_XML (object)->content_type,
-      SWFDEC_AS_STR_application_x_www_form_urlencoded);
-
-  SWFDEC_XML_NODE (object)->name = NULL;
+  xml = g_object_new (SWFDEC_TYPE_XML, "context", cx, NULL);
+  swfdec_xml_node_init_values (SWFDEC_XML_NODE (xml), SWFDEC_XML_NODE_ELEMENT, SWFDEC_AS_STR_EMPTY);
+  SWFDEC_XML_NODE (xml)->name = NULL;
+  swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (xml));
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  /* ??? */
+  if (!SWFDEC_IS_VALID_XML_NODE (xml))
     return;
 
   if (argc >= 1 && !SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0])) {
-    swfdec_xml_parseXML (SWFDEC_XML (object),
+    swfdec_xml_parseXML (xml,
 	swfdec_as_value_to_string (cx, &argv[0]));
   }
 }
@@ -940,20 +906,19 @@ SwfdecXml *
 swfdec_xml_new_no_properties (SwfdecAsContext *context, const char *str,
     gboolean ignore_white)
 {
+  SwfdecAsObject *object;
   SwfdecXml *xml;
 
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
 
   xml = g_object_new (SWFDEC_TYPE_XML, "context", context, NULL);
-
-  swfdec_as_object_set_constructor_by_name (SWFDEC_AS_OBJECT (xml), SWFDEC_AS_STR_XML, NULL);
   xml->ignore_white = ignore_white;
-
   swfdec_xml_node_init_values (SWFDEC_XML_NODE (xml),
       SWFDEC_XML_NODE_ELEMENT, SWFDEC_AS_STR_EMPTY);
 
-  SWFDEC_AS_VALUE_SET_STRING (&xml->content_type,
-      SWFDEC_AS_STR_application_x_www_form_urlencoded);
+  object = swfdec_as_object_new (context, NULL);
+  swfdec_as_object_set_constructor_by_name (object, SWFDEC_AS_STR_XML, NULL);
+  swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (xml));
 
   if (str != NULL)
     swfdec_xml_parseXML (xml, str);
diff --git a/swfdec/swfdec_xml_node.c b/swfdec/swfdec_xml_node.c
index 019ae6f..23ecee6 100644
--- a/swfdec/swfdec_xml_node.c
+++ b/swfdec/swfdec_xml_node.c
@@ -1,5 +1,5 @@
 /* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2007-2008 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
@@ -36,7 +36,7 @@
 #include "swfdec_load_object.h"
 #include "swfdec_player_internal.h"
 
-G_DEFINE_TYPE (SwfdecXmlNode, swfdec_xml_node, SWFDEC_TYPE_AS_OBJECT)
+G_DEFINE_TYPE (SwfdecXmlNode, swfdec_xml_node, SWFDEC_TYPE_AS_RELAY)
 
 static void
 swfdec_xml_node_mark (SwfdecGcObject *object)
@@ -97,9 +97,9 @@ swfdec_xml_node_get_child (SwfdecXmlNode *node, gint32 index_)
 
   g_return_val_if_fail (SWFDEC_AS_VALUE_IS_OBJECT (&val), NULL);
   g_return_val_if_fail (SWFDEC_IS_VALID_XML_NODE (
-	SWFDEC_AS_VALUE_GET_OBJECT (&val)), NULL);
+	SWFDEC_AS_VALUE_GET_OBJECT (&val)->relay), NULL);
 
-  return SWFDEC_XML_NODE (SWFDEC_AS_VALUE_GET_OBJECT (&val));
+  return SWFDEC_XML_NODE (SWFDEC_AS_VALUE_GET_OBJECT (&val)->relay);
 }
 
 static gint32
@@ -130,15 +130,15 @@ swfdec_xml_node_update_child_nodes (SwfdecXmlNode *node)
 
   // remove old
   swfdec_as_value_set_integer (swfdec_gc_object_get_context (node), &val, 0);
-  swfdec_as_object_set_variable (SWFDEC_AS_OBJECT (node->child_nodes),
+  swfdec_as_object_set_variable (node->child_nodes,
       SWFDEC_AS_STR_length, &val);
 
   // add everything
   num = swfdec_xml_node_num_children (node);
   vals = g_malloc (sizeof (SwfdecAsValue) * num);
   for (i = 0; i < num; i++) {
-    SWFDEC_AS_VALUE_SET_OBJECT (&vals[i],
-	SWFDEC_AS_OBJECT (swfdec_xml_node_get_child (node, i)));
+    SWFDEC_AS_VALUE_SET_OBJECT (&vals[i], swfdec_as_relay_get_as_object (
+	  SWFDEC_AS_RELAY (swfdec_xml_node_get_child (node, i))));
   }
   swfdec_as_array_append_with_flags (node->child_nodes, num, vals,
       SWFDEC_AS_VARIABLE_CONSTANT);
@@ -255,21 +255,29 @@ static void
 swfdec_xml_node_get_nodeType (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  swfdec_as_value_set_integer (cx, ret, SWFDEC_XML_NODE (object)->type);
+  swfdec_as_value_set_integer (cx, ret, node->type);
 }
 
 static void
 swfdec_xml_node_get_nodeValue (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  if (SWFDEC_XML_NODE (object)->value != NULL) {
-    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_XML_NODE (object)->value);
+  if (node->value != NULL) {
+    SWFDEC_AS_VALUE_SET_STRING (ret, node->value);
   } else {
     SWFDEC_AS_VALUE_SET_NULL (ret);
   }
@@ -279,17 +287,15 @@ static void
 swfdec_xml_node_set_nodeValue (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
+  SwfdecXmlNode *node;
   const char *value;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "s", &value);
 
-  if (argc < 1)
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  value = swfdec_as_value_to_string (cx, &argv[0]);
-
-  SWFDEC_XML_NODE (object)->value = value;
+  node->value = value;
   SWFDEC_AS_VALUE_SET_STRING (ret, value);
 }
 
@@ -297,11 +303,15 @@ static void
 swfdec_xml_node_get_nodeName (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  if (SWFDEC_XML_NODE (object)->name != NULL) {
-    SWFDEC_AS_VALUE_SET_STRING (ret, SWFDEC_XML_NODE (object)->name);
+  if (node->name != NULL) {
+    SWFDEC_AS_VALUE_SET_STRING (ret, node->name);
   } else {
     SWFDEC_AS_VALUE_SET_NULL (ret);
   }
@@ -311,21 +321,19 @@ static void
 swfdec_xml_node_set_nodeName (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
+  SwfdecXmlNode *node;
   const char *name;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "s", &name);
 
-  if (argc < 1)
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
   // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]))
     return;
 
-  name = swfdec_as_value_to_string (cx, &argv[0]);
-
-  SWFDEC_XML_NODE (object)->name = name;
+  node->name = name;
   SWFDEC_AS_VALUE_SET_STRING (ret, name);
 }
 
@@ -352,16 +360,19 @@ swfdec_xml_node_do_get_prefix (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   const char *prefix;
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  if (SWFDEC_XML_NODE (object)->name == NULL) {
+  if (node->name == NULL) {
     SWFDEC_AS_VALUE_SET_NULL (ret);
     return;
   }
 
-  prefix = swfdec_xml_node_get_prefix (SWFDEC_XML_NODE (object));
+  prefix = swfdec_xml_node_get_prefix (node);
   if (prefix != NULL) {
     SWFDEC_AS_VALUE_SET_STRING (ret, prefix);
   } else {
@@ -374,16 +385,19 @@ swfdec_xml_node_get_localName (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   const char *p, *name;
+  SwfdecXmlNode *node;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  if (SWFDEC_XML_NODE (object)->name == NULL) {
+  if (node->name == NULL) {
     SWFDEC_AS_VALUE_SET_NULL (ret);
     return;
   }
 
-  name = SWFDEC_XML_NODE (object)->name;
+  name = node->name;
   p = strchr (name, ':');
   if (p == NULL || *(p + 1) == '\0') {
     SWFDEC_AS_VALUE_SET_STRING (ret, name);
@@ -392,7 +406,7 @@ swfdec_xml_node_get_localName (SwfdecAsContext *cx, SwfdecAsObject *object,
   p++;
 
   SWFDEC_AS_VALUE_SET_STRING (ret,
-      swfdec_as_context_give_string (cx, g_strdup (p)));
+      swfdec_as_context_get_string (cx, p));
 }
 
 static void
@@ -400,17 +414,20 @@ swfdec_xml_node_get_namespaceURI (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   const char *uri;
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  if (SWFDEC_XML_NODE (object)->name == NULL) {
+  if (node->name == NULL) {
     SWFDEC_AS_VALUE_SET_NULL (ret);
     return;
   }
 
-  uri = swfdec_xml_node_getNamespaceForPrefix (SWFDEC_XML_NODE (object),
-      swfdec_xml_node_get_prefix (SWFDEC_XML_NODE (object)));
+  uri = swfdec_xml_node_getNamespaceForPrefix (node,
+      swfdec_xml_node_get_prefix (node));
   if (uri != NULL) {
     SWFDEC_AS_VALUE_SET_STRING (ret, uri);
   } else {
@@ -422,22 +439,30 @@ static void
 swfdec_xml_node_get_attributes (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_XML_NODE (object)->attributes);
+  SWFDEC_AS_VALUE_SET_OBJECT (ret, node->attributes);
 }
 
 static void
 swfdec_xml_node_get_parentNode (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  if (SWFDEC_XML_NODE (object)->parent != NULL) {
-    SWFDEC_AS_VALUE_SET_OBJECT (ret,
-	SWFDEC_AS_OBJECT (SWFDEC_XML_NODE (object)->parent));
+  if (node->parent != NULL) {
+    SWFDEC_AS_VALUE_SET_OBJECT (ret, 
+	swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (node->parent)));
   } else {
     SWFDEC_AS_VALUE_SET_NULL (ret);
   }
@@ -465,13 +490,16 @@ swfdec_xml_node_get_previousSibling (SwfdecAsContext *cx,
     SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecXmlNode *sibling;
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  sibling = swfdec_xml_node_previousSibling (SWFDEC_XML_NODE (object));
+  sibling = swfdec_xml_node_previousSibling (node);
   if (sibling != NULL) {
-    SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (sibling));
+    SWFDEC_AS_VALUE_SET_OBJECT (ret, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sibling)));
   } else {
     SWFDEC_AS_VALUE_SET_NULL (ret);
   }
@@ -496,13 +524,16 @@ swfdec_xml_node_get_nextSibling (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecXmlNode *sibling;
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  sibling = swfdec_xml_node_nextSibling (SWFDEC_XML_NODE (object));
+  sibling = swfdec_xml_node_nextSibling (node);
   if (sibling != NULL) {
-    SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (sibling));
+    SWFDEC_AS_VALUE_SET_OBJECT (ret, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sibling)));
   } else {
     SWFDEC_AS_VALUE_SET_NULL (ret);
   }
@@ -513,13 +544,16 @@ swfdec_xml_node_get_firstChild (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecXmlNode *child;
+  SwfdecXmlNode *node;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  child = swfdec_xml_node_get_child (SWFDEC_XML_NODE (object), 0);
+  child = swfdec_xml_node_get_child (node, 0);
   if (child != NULL) {
-    SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (child));
+    SWFDEC_AS_VALUE_SET_OBJECT (ret, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child)));
   } else {
     SWFDEC_AS_VALUE_SET_NULL (ret);
   }
@@ -531,31 +565,37 @@ swfdec_xml_node_get_lastChild (SwfdecAsContext *cx, SwfdecAsObject *object,
 {
   gint32 num;
   SwfdecXmlNode *child;
+  SwfdecXmlNode *node;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  num = swfdec_xml_node_num_children (SWFDEC_XML_NODE (object));
+  num = swfdec_xml_node_num_children (node);
   if (num == 0) {
     SWFDEC_AS_VALUE_SET_NULL (ret);
     return;
   }
 
-  child = swfdec_xml_node_get_child (SWFDEC_XML_NODE (object), num - 1);
+  child = swfdec_xml_node_get_child (node, num - 1);
   g_assert (child != NULL);
 
-  SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (child));
+  SWFDEC_AS_VALUE_SET_OBJECT (ret, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child)));
 }
 
 static void
 swfdec_xml_node_get_childNodes (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  SWFDEC_AS_VALUE_SET_OBJECT (ret,
-      SWFDEC_AS_OBJECT (SWFDEC_XML_NODE (object)->child_nodes));
+  SWFDEC_AS_VALUE_SET_OBJECT (ret, node->child_nodes);
 }
 
 SWFDEC_AS_NATIVE (253, 7, swfdec_xml_node_do_getNamespaceForPrefix)
@@ -563,9 +603,12 @@ void
 swfdec_xml_node_do_getNamespaceForPrefix (SwfdecAsContext *cx,
     SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  const char *namespace;
+  const char *namespace, *prefix;
+  SwfdecXmlNode *node;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "|s", &prefix);
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
   if (argc < 1) {
@@ -573,8 +616,7 @@ swfdec_xml_node_do_getNamespaceForPrefix (SwfdecAsContext *cx,
     return;
   }
 
-  namespace = swfdec_xml_node_getNamespaceForPrefix (SWFDEC_XML_NODE (object),
-      swfdec_as_value_to_string (cx, &argv[0]));
+  namespace = swfdec_xml_node_getNamespaceForPrefix (node, prefix);
 
   if (namespace != NULL) {
     SWFDEC_AS_VALUE_SET_STRING (ret, namespace);
@@ -588,9 +630,12 @@ void
 swfdec_xml_node_do_getPrefixForNamespace (SwfdecAsContext *cx,
     SwfdecAsObject *object, guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  const char *prefix;
+  const char *namespace, *prefix;
+  SwfdecXmlNode *node;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "|s", &namespace);
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
   if (argc < 1) {
@@ -598,8 +643,7 @@ swfdec_xml_node_do_getPrefixForNamespace (SwfdecAsContext *cx,
     return;
   }
 
-  prefix = swfdec_xml_node_getPrefixForNamespace (SWFDEC_XML_NODE (object),
-      swfdec_as_value_to_string (cx, &argv[0]));
+  prefix = swfdec_xml_node_getPrefixForNamespace (node, namespace);
 
   if (prefix != NULL) {
     SWFDEC_AS_VALUE_SET_STRING (ret, prefix);
@@ -633,8 +677,6 @@ swfdec_xml_node_clone (SwfdecAsContext *cx, SwfdecXmlNode *node, gboolean deep)
   g_assert (SWFDEC_IS_VALID_XML_NODE (node));
 
   new = swfdec_xml_node_new (cx, SWFDEC_XML_NODE_ELEMENT, SWFDEC_AS_STR_EMPTY);
-  if (new == NULL)
-    return NULL;
 
   new->valid = TRUE;
   new->type = node->type;
@@ -653,10 +695,8 @@ swfdec_xml_node_clone (SwfdecAsContext *cx, SwfdecXmlNode *node, gboolean deep)
     for (i = 0; i < num; i++) {
       child = swfdec_xml_node_get_child (node, i);
       child_new = swfdec_xml_node_clone (cx, child, TRUE);
-      if (child_new == NULL)
-	return NULL;
       child_new->parent = new;
-      SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (child_new));
+      SWFDEC_AS_VALUE_SET_OBJECT (&val, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child_new)));
       swfdec_as_array_push (new->children, &val);
     }
 
@@ -671,23 +711,17 @@ void
 swfdec_xml_node_cloneNode (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  gboolean deep;
-  SwfdecXmlNode *new;
-
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
-    return;
+  gboolean deep = FALSE;
+  SwfdecXmlNode *new, *node;
 
-  if (argc >= 1) {
-    deep = swfdec_as_value_to_boolean (cx, &argv[0]);
-  } else {
-    deep = FALSE;
-  }
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "|b", &deep);
 
-  new = swfdec_xml_node_clone (cx, SWFDEC_XML_NODE (object), deep);
-  if (new == NULL)
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  SWFDEC_AS_VALUE_SET_OBJECT (ret, SWFDEC_AS_OBJECT (new));
+  new = swfdec_xml_node_clone (cx, node, deep);
+
+  SWFDEC_AS_VALUE_SET_OBJECT (ret, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (new)));
 }
 
 void
@@ -713,10 +747,14 @@ void
 swfdec_xml_node_do_removeNode (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  swfdec_xml_node_removeNode (SWFDEC_XML_NODE (object));
+  swfdec_xml_node_removeNode (node);
 }
 
 void
@@ -755,7 +793,7 @@ swfdec_xml_node_insertAt (SwfdecXmlNode *node, SwfdecXmlNode *child, gint32 ind)
   swfdec_xml_node_removeNode (child);
 
   // insert child to node's child_nodes array
-  SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (child));
+  SWFDEC_AS_VALUE_SET_OBJECT (&val, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (child)));
   swfdec_as_array_insert (node->children, ind, &val);
   swfdec_xml_node_update_child_nodes (node);
 
@@ -770,38 +808,26 @@ swfdec_xml_node_insertBefore (SwfdecAsContext *cx, SwfdecAsObject *object,
 {
   gint32 i;
   SwfdecAsObject *child, *point;
+  SwfdecXmlNode *node, *child_node, *point_node;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "oo", &child, &point);
 
-  if (argc < 2)
+  if (!SWFDEC_IS_VALID_XML_NODE (node) ||
+      !SWFDEC_IS_VALID_XML_NODE (child->relay) ||
+      !SWFDEC_IS_VALID_XML_NODE (point->relay))
     return;
 
-  if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]))
-    return;
-
-  child = SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]);
-  if (!SWFDEC_IS_VALID_XML_NODE (child))
-    return;
+  child_node = SWFDEC_XML_NODE (child->relay);
+  point_node = SWFDEC_XML_NODE (point->relay);
 
   // special case
-  if (swfdec_xml_node_index_of_child (SWFDEC_XML_NODE (object),
-	SWFDEC_XML_NODE (child)) != -1)
-    return;
-
-  if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[1]))
+  if (swfdec_xml_node_index_of_child (node, child_node) != -1)
     return;
 
-  point = SWFDEC_AS_VALUE_GET_OBJECT (&argv[1]);
-  if (!SWFDEC_IS_VALID_XML_NODE (point))
-    return;
-
-  i = swfdec_xml_node_index_of_child (SWFDEC_XML_NODE (object),
-      SWFDEC_XML_NODE (point));
+  i = swfdec_xml_node_index_of_child (node, point_node);
 
   if (i != -1) {
-    swfdec_xml_node_insertAt (SWFDEC_XML_NODE (object),
-	SWFDEC_XML_NODE (child), i);
+    swfdec_xml_node_insertAt (node, child_node, i);
   }
 }
 
@@ -822,27 +848,21 @@ swfdec_xml_node_do_appendChild (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecAsObject *child;
+  SwfdecXmlNode *node, *child_node;
 
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
-    return;
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "o", &child);
 
-  if (argc < 1)
+  if (!SWFDEC_IS_VALID_XML_NODE (node) ||
+      !SWFDEC_IS_VALID_XML_NODE (child->relay))
     return;
 
-  if (!SWFDEC_AS_VALUE_IS_OBJECT (&argv[0]))
-    return;
-
-  child = SWFDEC_AS_VALUE_GET_OBJECT (&argv[0]);
-  if (!SWFDEC_IS_VALID_XML_NODE (child))
-    return;
+  child_node = SWFDEC_XML_NODE (child->relay);
 
   // special case
-  if (swfdec_xml_node_index_of_child (SWFDEC_XML_NODE (object),
-	SWFDEC_XML_NODE (child)) != -1)
+  if (swfdec_xml_node_index_of_child (node, child_node) != -1)
     return;
 
-  swfdec_xml_node_appendChild (SWFDEC_XML_NODE (object),
-      SWFDEC_XML_NODE (child));
+  swfdec_xml_node_appendChild (node, child_node);
 }
 
 SWFDEC_AS_NATIVE (253, 5, swfdec_xml_node_hasChildNodes)
@@ -850,14 +870,15 @@ void
 swfdec_xml_node_hasChildNodes (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  if (swfdec_xml_node_num_children (SWFDEC_XML_NODE (object)) > 0) {
-    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, TRUE);
-  } else {
-    SWFDEC_AS_VALUE_SET_BOOLEAN (ret, FALSE);
-  }
+  SWFDEC_AS_VALUE_SET_BOOLEAN (ret,
+      swfdec_xml_node_num_children (node) > 0);
 }
 
 static gboolean
@@ -883,12 +904,9 @@ static const char *
 swfdec_xml_node_toString (SwfdecXmlNode *node)
 {
   GString *string;
-  SwfdecAsObject *object;
 
   g_assert (SWFDEC_IS_VALID_XML_NODE (node));
 
-  object = SWFDEC_AS_OBJECT (node);
-
   string = g_string_new ("");
   if (SWFDEC_IS_XML (node)) {
     if (SWFDEC_XML (node)->xml_decl != NULL)
@@ -952,7 +970,7 @@ swfdec_xml_node_toString (SwfdecXmlNode *node)
       }
   }
 
-  return swfdec_as_context_give_string (swfdec_gc_object_get_context (object),
+  return swfdec_as_context_give_string (swfdec_gc_object_get_context (node),
       g_string_free (string, FALSE));
 }
 
@@ -961,27 +979,30 @@ void
 swfdec_xml_node_do_toString (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
-  if (!SWFDEC_IS_VALID_XML_NODE (object))
+  SwfdecXmlNode *node;
+
+  SWFDEC_AS_CHECK (SWFDEC_TYPE_XML_NODE, &node, "");
+
+  if (!SWFDEC_IS_VALID_XML_NODE (node))
     return;
 
-  SWFDEC_AS_VALUE_SET_STRING (ret,
-      swfdec_xml_node_toString (SWFDEC_XML_NODE (object)));
+  SWFDEC_AS_VALUE_SET_STRING (ret, swfdec_xml_node_toString (node));
 }
 
 void
 swfdec_xml_node_init_values (SwfdecXmlNode *node, int type, const char* value)
 {
-  SwfdecAsObject *object;
+  SwfdecAsContext *cx;
 
   g_return_if_fail (SWFDEC_IS_XML_NODE (node));
   g_return_if_fail (value != NULL);
 
-  object = SWFDEC_AS_OBJECT (node);
+  cx = swfdec_gc_object_get_context (node);
 
   node->valid = TRUE;
   node->parent = NULL;
-  node->children = swfdec_as_array_new (swfdec_gc_object_get_context (object));
-  node->attributes = swfdec_as_object_new_empty (swfdec_gc_object_get_context (object));
+  node->children = swfdec_as_array_new (cx);
+  node->attributes = swfdec_as_object_new_empty (cx);
   node->type = type;
   if (node->type == SWFDEC_XML_NODE_ELEMENT) {
     node->name = value;
@@ -989,7 +1010,7 @@ swfdec_xml_node_init_values (SwfdecXmlNode *node, int type, const char* value)
     node->value = value;
   }
 
-  node->child_nodes = swfdec_as_array_new (swfdec_gc_object_get_context (object));
+  node->child_nodes = swfdec_as_array_new (cx);
 }
 
 static void
@@ -1047,13 +1068,17 @@ swfdec_xml_node_new_no_properties (SwfdecAsContext *context,
     SwfdecXmlNodeType type, const char* value)
 {
   SwfdecXmlNode *node;
+  SwfdecAsObject *object;
 
   g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
   g_return_val_if_fail (value != NULL, NULL);
 
-  node = g_object_new (SWFDEC_TYPE_XML_NODE, "context", context, NULL);
-  swfdec_as_object_set_constructor_by_name (SWFDEC_AS_OBJECT (node),
+  object = swfdec_as_object_new (context, NULL);
+  swfdec_as_object_set_constructor_by_name (object,
       SWFDEC_AS_STR_XMLNode, NULL);
+
+  node = g_object_new (SWFDEC_TYPE_XML_NODE, "context", context, NULL);
+  swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (node));
   swfdec_xml_node_init_values (node, type, value);
 
   return node;
@@ -1070,29 +1095,29 @@ swfdec_xml_node_new (SwfdecAsContext *context, SwfdecXmlNodeType type,
   return swfdec_xml_node_new_no_properties (context, type, value);
 }
 
-SWFDEC_AS_CONSTRUCTOR (253, 0, swfdec_xml_node_construct, swfdec_xml_node_get_type)
+SWFDEC_AS_NATIVE (253, 0, swfdec_xml_node_construct)
 void
 swfdec_xml_node_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
     guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
+  SwfdecXmlNode *node;
+  const char *value;
+  int type;
+
   if (!swfdec_as_context_is_constructing (cx))
     return;
 
-  g_assert (SWFDEC_IS_XML_NODE (object));
-
-  if (argc < 2)
-    return;
+  SWFDEC_AS_CHECK (0, NULL, "is", &type, &value);
 
-  // special case
   if (SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[0]) ||
       SWFDEC_AS_VALUE_IS_UNDEFINED (&argv[1]))
     return;
 
   swfdec_xml_node_init_properties (cx);
 
-  swfdec_xml_node_init_values (SWFDEC_XML_NODE (object),
-      swfdec_as_value_to_integer (cx, &argv[0]),
-      swfdec_as_value_to_string (cx, &argv[1]));
+  node = g_object_new (SWFDEC_TYPE_XML_NODE, "context", cx, NULL);
+  swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (node));
+  swfdec_xml_node_init_values (node, type, value);
 
   SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
 }
diff --git a/swfdec/swfdec_xml_node.h b/swfdec/swfdec_xml_node.h
index 59c1f8e..ad5b35c 100644
--- a/swfdec/swfdec_xml_node.h
+++ b/swfdec/swfdec_xml_node.h
@@ -1,5 +1,5 @@
 /* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2007-2008 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
@@ -22,6 +22,7 @@
 #define _SWFDEC_XML_NODE_H_
 
 #include <swfdec/swfdec_as_object.h>
+#include <swfdec/swfdec_as_relay.h>
 #include <swfdec/swfdec_types.h>
 #include <swfdec/swfdec_script.h>
 #include <swfdec/swfdec_player.h>
@@ -53,10 +54,11 @@ typedef struct _SwfdecXmlNodeClass SwfdecXmlNodeClass;
 #define SWFDEC_XML_NODE_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_XML_NODE, SwfdecXmlNodeClass))
 #define SWFDEC_XML_NODE_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_XML_NODE, SwfdecXmlNodeClass))
 
-#define SWFDEC_IS_VALID_XML_NODE(obj)           (SWFDEC_IS_XML_NODE (obj) && SWFDEC_XML_NODE (obj)->valid)
+#define SWFDEC_IS_VALID_XML_NODE(obj)		(SWFDEC_IS_XML_NODE (obj) && SWFDEC_XML_NODE (obj)->valid)
+#define SWFDEC_VALID_XML_NODE_FROM_AS_OBJECT(obj) (SWFDEC_IS_VALID_XML_NODE (SWFDEC_XML_NODE ((obj)->relay) ? SWFDEC_XML_NODE ((obj)->relay) : NULL)
 
 struct _SwfdecXmlNode {
-  SwfdecAsObject	object;
+  SwfdecAsRelay		relay;
 
   gboolean		valid;
 
commit b29e035eb37287639579fad0cdabf131b140f05f
Author: Benjamin Otte <otte at gnome.org>
Date:   Wed Oct 22 13:56:39 2008 +0200

    make MovieClipLoader a relay

diff --git a/swfdec/swfdec_movie_clip_loader.c b/swfdec/swfdec_movie_clip_loader.c
index 902f2e2..d8a15aa 100644
--- a/swfdec/swfdec_movie_clip_loader.c
+++ b/swfdec/swfdec_movie_clip_loader.c
@@ -31,7 +31,7 @@
 #include "swfdec_resource.h"
 
 
-G_DEFINE_TYPE (SwfdecMovieClipLoader, swfdec_movie_clip_loader, SWFDEC_TYPE_AS_OBJECT)
+G_DEFINE_TYPE (SwfdecMovieClipLoader, swfdec_movie_clip_loader, SWFDEC_TYPE_AS_RELAY)
 
 static void
 swfdec_movie_clip_loader_class_init (SwfdecMovieClipLoaderClass *klass)
@@ -43,23 +43,29 @@ swfdec_movie_clip_loader_init (SwfdecMovieClipLoader *movie_clip_loader)
 {
 }
 
-SWFDEC_AS_CONSTRUCTOR (112, 0, swfdec_movie_clip_loader_construct, swfdec_movie_clip_loader_get_type)
+SWFDEC_AS_NATIVE (112, 0, swfdec_movie_clip_loader_construct)
 void 
 swfdec_movie_clip_loader_construct (SwfdecAsContext *cx, SwfdecAsObject *object,
-    guint argc, SwfdecAsValue *argv, SwfdecAsValue *rval)
+    guint argc, SwfdecAsValue *argv, SwfdecAsValue *ret)
 {
   SwfdecAsValue val;
   SwfdecAsObject *array;
+  SwfdecMovieClipLoader *loader;
 
   if (!swfdec_as_context_is_constructing (cx))
     return;
 
+  loader = g_object_new (SWFDEC_TYPE_MOVIE_CLIP_LOADER, "context", cx, NULL);
+  swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (loader));
+
   array = swfdec_as_array_new (cx);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, object);
   swfdec_as_array_push (array, &val);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, array);
   swfdec_as_object_set_variable_and_flags (object, SWFDEC_AS_STR__listeners, 
       &val, SWFDEC_AS_VARIABLE_HIDDEN | SWFDEC_AS_VARIABLE_PERMANENT);
+
+  SWFDEC_AS_VALUE_SET_OBJECT (ret, object);
 }
 
 SWFDEC_AS_NATIVE (112, 100, swfdec_movie_clip_loader_loadClip)
diff --git a/swfdec/swfdec_movie_clip_loader.h b/swfdec/swfdec_movie_clip_loader.h
index 5bf7aae..38bf13e 100644
--- a/swfdec/swfdec_movie_clip_loader.h
+++ b/swfdec/swfdec_movie_clip_loader.h
@@ -1,5 +1,5 @@
 /* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte at gnome.org>
+ * Copyright (C) 2007-2008 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
@@ -20,7 +20,7 @@
 #ifndef _SWFDEC_MOVIE_CLIP_LOADER_H_
 #define _SWFDEC_MOVIE_CLIP_LOADER_H_
 
-#include <swfdec/swfdec_as_object.h>
+#include <swfdec/swfdec_as_relay.h>
 
 G_BEGIN_DECLS
 
@@ -36,12 +36,12 @@ typedef struct _SwfdecMovieClipLoaderClass SwfdecMovieClipLoaderClass;
 
 struct _SwfdecMovieClipLoader
 {
-  SwfdecAsObject	object;
+  SwfdecAsRelay		relay;
 };
 
 struct _SwfdecMovieClipLoaderClass
 {
-  SwfdecAsObjectClass 	object_class;
+  SwfdecAsRelayClass 	relay_class;
 };
 
 GType swfdec_movie_clip_loader_get_type (void);
diff --git a/swfdec/swfdec_resource.c b/swfdec/swfdec_resource.c
index 51e1b2a..c14fa6f 100644
--- a/swfdec/swfdec_resource.c
+++ b/swfdec/swfdec_resource.c
@@ -157,7 +157,7 @@ swfdec_resource_emit_signal (SwfdecResource *resource, const char *name, gboolea
     memcpy (&vals[skip], args, sizeof (SwfdecAsValue) * n_args);
   /* FIXME: what's the correct sandbox here? */
   swfdec_sandbox_use (resource->clip_loader_sandbox);
-  swfdec_as_object_call (SWFDEC_AS_OBJECT (resource->clip_loader), SWFDEC_AS_STR_broadcastMessage, 
+  swfdec_as_relay_call (SWFDEC_AS_RELAY (resource->clip_loader), SWFDEC_AS_STR_broadcastMessage, 
       n_args + skip, vals, NULL);
   swfdec_sandbox_unuse (resource->clip_loader_sandbox);
 }


More information about the Swfdec-commits mailing list