[Swfdec-commits] Branch 'abc' - swfdec/Makefile.am swfdec/swfdec_abc_file.c swfdec/swfdec_abc_file.h swfdec/swfdec_abc_function.c swfdec/swfdec_abc_function.h swfdec/swfdec_abc_global.c swfdec/swfdec_abc_global.h swfdec/swfdec_abc_interpret.c swfdec/swfdec_abc_pool.c swfdec/swfdec_abc_pool.h swfdec/swfdec_abc_traits.c swfdec/swfdec_abc_traits.h swfdec/swfdec_abc_types.h swfdec/swfdec_as_context.c swfdec/swfdec_sandbox_abc.c swfdec/swfdec_sandbox_as.c swfdec/swfdec_sprite_movie.c

Benjamin Otte company at kemper.freedesktop.org
Sat Aug 23 07:01:57 PDT 2008


 swfdec/Makefile.am            |    4 
 swfdec/swfdec_abc_file.c      | 1163 ------------------------------------------
 swfdec/swfdec_abc_file.h      |  108 ---
 swfdec/swfdec_abc_function.c  |    4 
 swfdec/swfdec_abc_function.h  |    2 
 swfdec/swfdec_abc_global.c    |   18 
 swfdec/swfdec_abc_global.h    |    2 
 swfdec/swfdec_abc_interpret.c |    4 
 swfdec/swfdec_abc_pool.c      | 1163 ++++++++++++++++++++++++++++++++++++++++++
 swfdec/swfdec_abc_pool.h      |  108 +++
 swfdec/swfdec_abc_traits.c    |    6 
 swfdec/swfdec_abc_traits.h    |    2 
 swfdec/swfdec_abc_types.h     |    2 
 swfdec/swfdec_as_context.c    |    2 
 swfdec/swfdec_sandbox_abc.c   |    4 
 swfdec/swfdec_sandbox_as.c    |    2 
 swfdec/swfdec_sprite_movie.c  |    6 
 17 files changed, 1300 insertions(+), 1300 deletions(-)

New commits:
commit f89ea4cc90af26dff8ff047a4f53dc67ba3e4a10
Author: Benjamin Otte <otte at gnome.org>
Date:   Sat Aug 23 16:00:20 2008 +0200

    rename SwfdecAbcFile to SwfdecAbcPool

diff --git a/swfdec/Makefile.am b/swfdec/Makefile.am
index 8a737f1..6844454 100644
--- a/swfdec/Makefile.am
+++ b/swfdec/Makefile.am
@@ -11,7 +11,6 @@ lib_LTLIBRARIES = libswfdec- at SWFDEC_MAJORMINOR@.la
 # these are files that must be in SRCDIR
 libswfdec_source_files = \
 	swfdec_abc_class.c \
-	swfdec_abc_file.c \
 	swfdec_abc_function.c \
 	swfdec_abc_global.c \
 	swfdec_abc_interpret.c \
@@ -20,6 +19,7 @@ libswfdec_source_files = \
 	swfdec_abc_namespace.c \
 	swfdec_abc_ns_set.c \
 	swfdec_abc_object.c \
+	swfdec_abc_pool.c \
 	swfdec_abc_scope_chain.c \
 	swfdec_abc_script.c \
 	swfdec_abc_traits.c \
@@ -243,7 +243,6 @@ libswfdec_ at SWFDEC_MAJORMINOR@include_HEADERS = $(public_headers) swfdec_enums.h
 
 noinst_HEADERS = \
 	swfdec_abc_class.h \
-	swfdec_abc_file.h \
 	swfdec_abc_function.h \
 	swfdec_abc_global.h \
 	swfdec_abc_initialize.h \
@@ -253,6 +252,7 @@ noinst_HEADERS = \
 	swfdec_abc_native.h \
 	swfdec_abc_ns_set.h \
 	swfdec_abc_object.h \
+	swfdec_abc_pool.h \
 	swfdec_abc_scope_chain.h \
 	swfdec_abc_script.h \
 	swfdec_abc_traits.h \
diff --git a/swfdec/swfdec_abc_file.c b/swfdec/swfdec_abc_file.c
deleted file mode 100644
index 0e53bf2..0000000
--- a/swfdec/swfdec_abc_file.c
+++ /dev/null
@@ -1,1163 +0,0 @@
-/* Swfdec
- * Copyright (C) 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
- * 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 "swfdec_abc_file.h"
-
-#include <math.h>
-
-#include "swfdec_abc_function.h"
-#include "swfdec_abc_internal.h"
-#include "swfdec_abc_script.h"
-#include "swfdec_abc_traits.h"
-#include "swfdec_as_frame.h" /* default stub */
-#include "swfdec_as_strings.h"
-#include "swfdec_debug.h"
-
-/*** SWFDEC_ABC_FILE ***/
-
-G_DEFINE_TYPE (SwfdecAbcFile, swfdec_abc_file, SWFDEC_TYPE_GC_OBJECT)
-
-static void
-swfdec_abc_file_dispose (GObject *object)
-{
-  SwfdecAbcFile *file = SWFDEC_ABC_FILE (object);
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-
-  if (file->n_ints) {
-    swfdec_as_context_free (context, file->n_ints * sizeof (int), file->ints);
-  }
-  if (file->n_uints) {
-    swfdec_as_context_free (context, file->n_uints * sizeof (guint), file->uints);
-  }
-  if (file->n_doubles) {
-    swfdec_as_context_free (context, file->n_doubles * sizeof (double), file->doubles);
-  }
-  if (file->n_strings) {
-    swfdec_as_context_free (context, file->n_strings * sizeof (const char *), file->strings);
-  }
-  if (file->n_namespaces) {
-    swfdec_as_context_free (context, file->n_namespaces * sizeof (SwfdecAbcNamespace *),
-	file->namespaces);
-  }
-  if (file->n_nssets) {
-    guint i;
-    for (i = 0; i < file->n_nssets; i++) {
-      swfdec_abc_ns_set_free (file->nssets[i]);
-    }
-    swfdec_as_context_free (context, file->n_nssets * sizeof (SwfdecAbcNsSet *),
-	file->nssets);
-  }
-  if (file->n_multinames) {
-    swfdec_as_context_free (context, file->n_multinames * sizeof (SwfdecAbcMultiname),
-	file->multinames);
-  }
-  if (file->n_functions) {
-    swfdec_as_context_free (context, file->n_functions * sizeof (SwfdecAbcFunction *),
-	file->functions);
-  }
-  if (file->n_classes) {
-    swfdec_as_context_free (context, file->n_classes * sizeof (SwfdecAbcFunction *),
-	file->instances);
-    swfdec_as_context_free (context, file->n_classes * sizeof (SwfdecAbcFunction *),
-	file->classes);
-  }
-
-  G_OBJECT_CLASS (swfdec_abc_file_parent_class)->dispose (object);
-}
-
-static void
-swfdec_abc_file_mark (SwfdecGcObject *object)
-{
-  SwfdecAbcFile *file = SWFDEC_ABC_FILE (object);
-  guint i;
-
-  for (i = 0; i < file->n_strings; i++) {
-    swfdec_as_string_mark (file->strings[i]);
-  }
-  for (i = 1; i < file->n_namespaces; i++) {
-    swfdec_gc_object_mark (file->namespaces[i]);
-  }
-  for (i = 1; i < file->n_functions; i++) {
-    if (file->functions[i])
-      swfdec_gc_object_mark (file->functions[i]);
-  }
-  for (i = 1; i < file->n_classes; i++) {
-    if (file->classes[i])
-      swfdec_gc_object_mark (file->classes[i]);
-  }
-
-  if (file->main)
-    swfdec_gc_object_mark (file->main);
-
-  SWFDEC_GC_OBJECT_CLASS (swfdec_abc_file_parent_class)->mark (object);
-}
-
-static void
-swfdec_abc_file_class_init (SwfdecAbcFileClass *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  SwfdecGcObjectClass *gc_class = SWFDEC_GC_OBJECT_CLASS (klass);
-
-  object_class->dispose = swfdec_abc_file_dispose;
-
-  gc_class->mark = swfdec_abc_file_mark;
-}
-
-static void
-swfdec_abc_file_init (SwfdecAbcFile *date)
-{
-}
-
-/*** PARSING ***/
-
-#define READ_U30(x, bits) G_STMT_START{ \
-  x = swfdec_bits_get_vu32 (bits); \
-  if (x >= (1 << 30)) { \
-    SWFDEC_ERROR ("invalid U30 value %u\n", x); \
-    return FALSE; \
-  } \
-}G_STMT_END;
-#define THROW(file, ...) G_STMT_START{ \
-  swfdec_as_context_throw_abc (swfdec_gc_object_get_context (file), \
-      SWFDEC_ABC_TYPE_VERIFY_ERROR, __VA_ARGS__); \
-  return FALSE; \
-}G_STMT_END
-
-static gboolean
-swfdec_abc_file_parse_qname (SwfdecAbcFile *file, SwfdecBits *bits, SwfdecAbcNamespace **ns, const char **name)
-{
-  SwfdecAbcMultiname *mn;
-  guint id;
-
-  READ_U30 (id, bits);
-  if (id == 0 || id >= file->n_multinames)
-    THROW (file, "Cpool index %u is out of range %u.", id, file->n_multinames);
-  mn = &file->multinames[id];
-  if (!swfdec_abc_multiname_is_qualified (mn))
-    THROW (file, "Cpool entry %u is wrong type.", id);
-
-  *ns = mn->ns;
-  *name = mn->name;
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_constants (SwfdecAbcFile *file, SwfdecBits *bits)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  guint i;
-
-  SWFDEC_LOG ("parsing ABC block");
-  /* read all integers */
-  READ_U30 (file->n_ints, bits);
-  SWFDEC_LOG ("%u integers", file->n_ints);
-  if (file->n_ints) {
-    file->ints = swfdec_as_context_try_new (context, int, file->n_ints);
-    if (file->ints == NULL) {
-      file->n_ints = 0;
-      return FALSE;
-    }
-    for (i = 1; i < file->n_ints && swfdec_bits_left (bits); i++) {
-      file->ints[i] = swfdec_bits_get_vs32 (bits);
-      SWFDEC_LOG ("  int %u: %d", i, file->ints[i]);
-    }
-  }
-
-  /* read all unsigned integers */
-  READ_U30 (file->n_uints, bits);
-  SWFDEC_LOG ("%u unsigned integers", file->n_uints);
-  if (file->n_uints) {
-    file->uints = swfdec_as_context_try_new (context, guint, file->n_uints);
-    if (file->uints == NULL) {
-      file->n_uints = 0;
-      return FALSE;
-    }
-    for (i = 1; i < file->n_uints && swfdec_bits_left (bits); i++) {
-      file->uints[i] = swfdec_bits_get_vu32 (bits);
-      SWFDEC_LOG ("  uint %u: %u", i, file->uints[i]);
-    }
-  }
-
-  /* read all doubles */
-  READ_U30 (file->n_doubles, bits);
-  SWFDEC_LOG ("%u doubles", file->n_doubles);
-  if (file->n_doubles) {
-    file->doubles = swfdec_as_context_try_new (context, double, file->n_doubles);
-    if (file->doubles == NULL) {
-      file->n_doubles = 0;
-      return FALSE;
-    }
-    file->doubles[0] = NAN;
-    for (i = 1; i < file->n_doubles && swfdec_bits_left (bits); i++) {
-      file->doubles[i] = swfdec_bits_get_ldouble (bits);
-      SWFDEC_LOG ("  double %u: %g", i, file->doubles[i]);
-    }
-  }
-
-  /* read all strings */
-  READ_U30 (file->n_strings, bits);
-  SWFDEC_LOG ("%u strings", file->n_strings);
-  if (file->n_strings) {
-    file->strings = swfdec_as_context_try_new (context, const char *, file->n_strings);
-    if (file->strings == NULL) {
-      file->n_strings = 0;
-      return FALSE;
-    }
-    for (i = 1; i < file->n_strings; i++) {
-      guint len;
-      char *s;
-      READ_U30 (len, bits);
-      s = swfdec_bits_get_string_length (bits, len, 9);
-      if (s == NULL)
-	return FALSE;
-      file->strings[i] = swfdec_as_context_give_string (context, s);
-      SWFDEC_LOG ("  string %u: %s", i, file->strings[i]);
-    }
-  }
-
-  /* read all namespaces */
-  READ_U30 (file->n_namespaces, bits);
-  SWFDEC_LOG ("%u namespaces", file->n_namespaces);
-  if (file->n_namespaces) {
-    file->namespaces = swfdec_as_context_try_new (context, SwfdecAbcNamespace *, file->n_namespaces);
-    if (file->namespaces == NULL) {
-      file->n_namespaces = 0;
-      return FALSE;
-    }
-    for (i = 1; i < file->n_namespaces; i++) {
-      SwfdecAbcNamespaceType type;
-      guint id;
-      switch (swfdec_bits_get_u8 (bits)) {
-	case SWFDEC_ABC_CONST_PRIVATE_NAMESPACE:
-	  type = SWFDEC_ABC_NAMESPACE_PRIVATE;
-	  break;
-	case SWFDEC_ABC_CONST_NAMESPACE:
-	case SWFDEC_ABC_CONST_PACKAGE_NAMESPACE:
-	  type = SWFDEC_ABC_NAMESPACE_PUBLIC;
-	  break;
-	case SWFDEC_ABC_CONST_INTERNAL_NAMESPACE:
-	  type = SWFDEC_ABC_NAMESPACE_PACKAGE;
-	  break;
-	case SWFDEC_ABC_CONST_PROTECTED_NAMESPACE:
-	  type = SWFDEC_ABC_NAMESPACE_PROTECTED;
-	  break;
-	case SWFDEC_ABC_CONST_EXPLICIT_NAMESPACE:
-	  type = SWFDEC_ABC_NAMESPACE_EXPLICIT;
-	  break;
-	case SWFDEC_ABC_CONST_STATIC_PROTECTED_NAMESPACE:
-	  type = SWFDEC_ABC_NAMESPACE_STATIC_PROTECTED;
-	  break;
-	default:
-	  THROW (file, "Cpool entry %u is wrong type.", i);
-      }
-      READ_U30 (id, bits);
-      if (id == 0) {
-	SWFDEC_LOG ("  namespace %u: undefined", i);
-	file->namespaces[i] = (type == SWFDEC_ABC_NAMESPACE_PRIVATE ? 
-	    swfdec_abc_namespace_new : swfdec_as_context_get_namespace) (context,
-	    type, NULL, SWFDEC_AS_STR_undefined);
-      } else if (id < file->n_strings) {
-	SWFDEC_LOG ("  namespace %u: %s", i, file->strings[id]);
-	file->namespaces[i] = (type == SWFDEC_ABC_NAMESPACE_PRIVATE ? 
-	    swfdec_abc_namespace_new : swfdec_as_context_get_namespace) (context,
-	    type, NULL, file->strings[id]);
-      } else {
-	THROW (file, "Cpool index %u is out of range %u.", id, file->n_strings);
-      }
-    }
-  }
-
-  /* read all namespace sets */
-  READ_U30 (file->n_nssets, bits);
-  SWFDEC_LOG ("%u namespace sets", file->n_nssets);
-  if (file->n_nssets) {
-    file->nssets = swfdec_as_context_try_new (context, SwfdecAbcNsSet *, file->n_nssets);
-    if (file->nssets == NULL) {
-      file->n_nssets = 0;
-      return FALSE;
-    }
-    for (i = 0; i < file->n_nssets; i++) {
-      file->nssets[i] = swfdec_abc_ns_set_new ();
-    }
-    for (i = 1; i < file->n_nssets; i++) {
-      guint j, len;
-      READ_U30 (len, bits);
-      for (j = 0; j < len; j++) {
-	guint ns;
-	READ_U30 (ns, bits);
-	if (ns == 0 || ns >= file->n_namespaces)
-	  return FALSE;
-	swfdec_abc_ns_set_add (file->nssets[i], file->namespaces[ns]);
-      }
-      SWFDEC_LOG ("  ns set %u: %u namespaces", i, len);
-    }
-  }
-
-  /* read all multinames */
-  READ_U30 (file->n_multinames, bits);
-  SWFDEC_LOG ("%u multinames", file->n_multinames);
-  if (file->n_multinames) {
-    guint nsid, nameid;
-    file->multinames = swfdec_as_context_try_new (context, SwfdecAbcMultiname, file->n_multinames);
-    if (file->multinames == NULL) {
-      file->n_multinames = 0;
-      return FALSE;
-    }
-    for (i = 1; i < file->n_multinames; i++) {
-      switch (swfdec_bits_get_u8 (bits)) {
-	case 0x0D:
-	  SWFDEC_FIXME ("implement attributes");
-	case 0x07:
-	  READ_U30 (nsid, bits);
-	  if (nsid >= file->n_namespaces)
-	    THROW (file, "Cpool index %u is out of range %u.", nsid, file->n_namespaces);
-	  READ_U30 (nameid, bits);
-	  if (nameid >= file->n_strings)
-	    THROW (file, "Cpool index %u is out of range %u.", nameid, file->n_strings);
-	  swfdec_abc_multiname_init (&file->multinames[i],
-	      nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : file->strings[nameid],
-	      nsid == 0 ? SWFDEC_ABC_MULTINAME_ANY : file->namespaces[nsid],
-	      NULL);
-	  break;
-	case 0x10:
-	  SWFDEC_FIXME ("implement attributes");
-	case 0x0F:
-	  READ_U30 (nameid, bits);
-	  if (nameid >= file->n_strings)
-	    THROW (file, "Cpool index %u is out of range %u.", nameid, file->n_strings);
-	  swfdec_abc_multiname_init (&file->multinames[i],
-	      nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : file->strings[nameid],
-	      NULL, NULL);
-	  break;
-	case 0x12:
-	  SWFDEC_FIXME ("implement attributes");
-	case 0x11:
-	  swfdec_abc_multiname_init (&file->multinames[i],
-	      NULL, NULL, NULL);
-	  break;
-	case 0x0E:
-	  SWFDEC_FIXME ("implement attributes");
-	case 0x09:
-	  READ_U30 (nameid, bits);
-	  if (nameid >= file->n_strings)
-	    THROW (file, "Cpool index %u is out of range %u.", nameid, file->n_strings);
-	  READ_U30 (nsid, bits);
-	  if (nsid >= file->n_nssets)
-	    THROW (file, "Cpool index %u is out of range %u.", nsid, file->n_nssets);
-	  swfdec_abc_multiname_init (&file->multinames[i],
-	      nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : file->strings[nameid],
-	      NULL, file->nssets[nsid]);
-	  break;
-	case 0x1C:
-	  SWFDEC_FIXME ("implement attributes");
-	case 0x1B:
-	  READ_U30 (nsid, bits);
-	  if (nsid >= file->n_nssets)
-	    THROW (file, "Cpool index %u is out of range %u.", nsid, file->n_nssets);
-	  swfdec_abc_multiname_init (&file->multinames[i],
-	      NULL, NULL, file->nssets[nsid]);
-	  break;
-	default:
-	  THROW (file, "Cpool entry %u is wrong type.", i);
-      }
-      SWFDEC_LOG ("  multiname %u: %s::%s", i, file->multinames[i].ns == NULL ? 
-	  (file->multinames[i].nsset ? "[SET]" : "[RUNTIME]") : 
-	  file->multinames[i].ns == SWFDEC_ABC_MULTINAME_ANY ? "[*]" : file->multinames[i].ns->uri,
-	  file->multinames[i].name == NULL ? "[RUNTIME]" : 
-	  file->multinames[i].name == SWFDEC_ABC_MULTINAME_ANY ? "[*]" : file->multinames[i].name);
-    }
-  }
-
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_method (SwfdecAbcFile *file, SwfdecBits *bits, SwfdecAbcTraits *traits, SwfdecAbcFunction **ret)
-{
-  guint id;
-
-  READ_U30 (id, bits);
-  if (id >= file->n_functions) {
-    THROW (file, "Method_info %u exceeds method_count=%u.", id, file->n_functions);
-  } else if (file->functions[id] == NULL) {
-    THROW (file, "MethodInfo-%u referenced before definition.", id);
-  } else if (traits) {
-    if (!swfdec_abc_function_bind (file->functions[id], traits)) {
-      THROW (file, "Function %s has already been bound to %s.", file->functions[id]->name,
-	  file->functions[id]->bound_traits->name);
-    }
-    g_assert (traits->construct == NULL);
-    traits->construct = file->functions[id];
-    SWFDEC_LOG ("binding method %u to traits %s", id, traits->name);
-  } else {
-    SWFDEC_LOG ("found method %u", id);
-  }
-  if (ret)
-    *ret = file->functions[id];
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_traits (SwfdecAbcFile *file, SwfdecAbcTraits *traits, SwfdecBits *bits)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  SwfdecAbcTraits *base = traits->base;
-  guint i, n_slots, n_methods, n_traits;
-  gboolean early, metadata;
-
-  READ_U30 (n_traits, bits);
-  SWFDEC_LOG ("%u traits", n_traits);
-
-  /* ensure we can copy protected traits from base class into new protected namespace */
-  traits->n_traits = n_traits;
-  if (base && base->protected_ns && traits->protected_ns) {
-    for (i = 0; i < base->n_traits; i++) {
-      if (base->traits[i].ns == base->protected_ns)
-	traits->n_traits++;
-    }
-  }
-
-  if (traits->n_traits) {
-    traits->traits = swfdec_as_context_try_new (context, SwfdecAbcTrait, traits->n_traits);
-    if (traits->traits == NULL) {
-      traits->n_traits = 0;
-      return FALSE;
-    }
-  }
-  if (base && base->protected_ns && traits->protected_ns) {
-    traits->n_traits = n_traits;
-    for (i = 0; i < base->n_traits; i++) {
-      if (base->traits[i].ns == base->protected_ns) {
-	traits->traits[traits->n_traits] = base->traits[i];
-	traits->traits[traits->n_traits].ns = traits->protected_ns;
-	traits->n_traits++;
-      }
-    }
-  }
-
-
-  if (base) {
-    n_slots = base->n_slots;
-    n_methods = base->n_methods;
-  } else {
-    n_slots = 0;
-    n_methods = 0;
-  }
-
-  early = base ? swfdec_abc_traits_allow_early_binding (traits) : TRUE;
-  SWFDEC_LOG ("  %sallowing early binding", early ? "" : "NOT ");
-
-  for (i = 0; i < n_traits; i++) {
-    SwfdecAbcTrait *trait = &traits->traits[i];
-    guint type;
-    SWFDEC_LOG ("trait %u", i);
-    if (!swfdec_abc_file_parse_qname (file, bits, &trait->ns, &trait->name))
-      return FALSE;
-    SWFDEC_LOG ("  name: %s::%s", trait->ns->uri, trait->name);
-
-    /* reserved = */ swfdec_bits_getbit (bits);
-    metadata = swfdec_bits_getbit (bits);
-    SWFDEC_LOG ("  metadata: %d", metadata);
-    trait->override = swfdec_bits_getbit (bits);
-    SWFDEC_LOG ("  override: %d", trait->override);
-    trait->final = swfdec_bits_getbit (bits);
-    SWFDEC_LOG ("  final: %d", trait->final);
-    type = swfdec_bits_getbits (bits, 4);
-    SWFDEC_LOG ("  type: %u", type);
-    switch (type) {
-      case 0: /* slot */
-      case 6: /* const */
-      case 4: /* class */
-	{
-          guint slot;
-	  READ_U30 (slot, bits);
-	  if (!early)
-	    slot = 0;
-	  if (slot == 0) {
-	    slot = n_slots;
-	    n_slots++;
-	    SWFDEC_LOG ("  slot: %u (automatic)", slot);
-	  } else {
-	    if (slot > n_traits || slot == 0)
-	      THROW (file, "The ABC data is corrupt, attempt to read out of bounds.");
-	    if (slot > n_slots)
-	      n_slots = slot;
-	    slot--;
-	    if (base && slot < base->n_slots)
-	      THROW (file, "Illegal override of %s in %s.", trait->name, traits->name);
-	    SWFDEC_LOG ("  slot: %u", slot);
-	  }
-
-	  if (swfdec_abc_traits_get_trait (traits, trait->ns, trait->name))
-	    THROW (file, "The ABC data is corrupt, attempt to read out of bounds.");
-				
-	  if (type == 4) {
-	    guint id;
-	    READ_U30 (id, bits);
-	    if (id >= file->n_classes)
-	      THROW (file, "ClassInfo %u exceeds class_count=%u.", id, file->n_functions);
-	    if (file->classes[id] == NULL)
-	      THROW (file, "ClassInfo-%u is referenced before definition.", id);
-
-	    trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_CONST, slot);
-	    trait->default_index = id;
-	    trait->default_type = G_MAXUINT; /* magic value */
-	  } else {
-	    g_assert (type == 0 || type == 6);
-	    READ_U30 (trait->traits_type, bits);
-	    READ_U30 (trait->default_index, bits);
-	    if (trait->default_index) {
-	      trait->default_type = swfdec_bits_get_u8 (bits);
-	    }
-	    trait->type = SWFDEC_ABC_BINDING_NEW (type == 0 ? SWFDEC_ABC_TRAIT_SLOT : SWFDEC_ABC_TRAIT_CONST, slot);
-	  }
-	}
-	break;
-      case 1: /* method */
-      case 2: /* getter */
-      case 3: /* setter */
-	{
-	  guint ignore, method_id;
-	  SwfdecAbcBinding bind;
-	  const SwfdecAbcTrait *found;
-	  SwfdecAbcFunction *fun;
-	  READ_U30 (ignore, bits);
-	  SWFDEC_LOG ("  display id = %u (ignored)", ignore);
-	  READ_U30 (method_id, bits);
-	  if (method_id >= file->n_functions) {
-	    THROW (file, "Method_info %u exceeds method_count=%u.", method_id, file->n_functions);
-	  } else if (file->functions[method_id] == NULL) {
-	    THROW (file, "MethodInfo-%u referenced before definition.", method_id);
-	  } else {
-	    fun = file->functions[method_id];
-	  }
-	  if (!swfdec_abc_function_bind (fun, traits)) {
-	    THROW (file, "Function %s has already been bound to %s.", traits->name,
-		fun->bound_traits->name);
-	  }
-
-	  if (traits->base && (found = swfdec_abc_traits_find_trait (traits->base,
-	      trait->ns == traits->protected_ns ? traits->base->protected_ns: trait->ns, 
-	      trait->name))) {
-	    bind = found->type;
-	    SWFDEC_LOG ("  found method %u of type %u to override", 
-		SWFDEC_ABC_BINDING_GET_ID (bind), SWFDEC_ABC_BINDING_GET_TYPE (bind));
-	    trait->default_index = found->default_index;
-	    trait->default_type = found->default_type;
-	  } else {
-	    bind = SWFDEC_ABC_BINDING_NONE;
-	  }
-
-	  if (type == 1) { 
-	    /* method */
-	    if (bind == SWFDEC_ABC_BINDING_NONE) {
-	      if (trait->override)
-		THROW (file, "Illegal override of %s in %s.", trait->name, traits->name);
-	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_METHOD, n_methods);
-	      SWFDEC_LOG ("  method: %u (new)", n_methods);
-	      n_methods++;
-	    } else if (SWFDEC_ABC_BINDING_IS_TYPE (bind, SWFDEC_ABC_TRAIT_METHOD)) {
-	      if (!trait->override)
-		THROW (file, "Illegal override of %s in %s.", trait->name, traits->name);
-	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_METHOD, 
-		  SWFDEC_ABC_BINDING_GET_ID (bind));
-	      SWFDEC_LOG ("  method: %u (override)", SWFDEC_ABC_BINDING_GET_ID (bind));
-	    } else {
-	      THROW (file, "The ABC data is corrupt, attempt to read out of bounds.");
-	    }
-	    trait->default_index = method_id;
-	  } else {
-	    SwfdecAbcTraitType ttype = type == 2 ? SWFDEC_ABC_TRAIT_GET : SWFDEC_ABC_TRAIT_SET;
-	    /* getter or setter */
-
-	    /* check override */
-	    if (bind == SWFDEC_ABC_BINDING_NONE) {
-	      if (trait->override)
-		THROW (file, "Illegal override of %s in %s.", trait->name, traits->name);
-	    } else if (SWFDEC_ABC_BINDING_IS_ACCESSOR (bind)) {
-	      if ((trait->override ? TRUE : FALSE) != ((SWFDEC_ABC_BINDING_GET_TYPE (bind) & ttype) == ttype))
-		THROW (file, "Illegal override of %s in %s.", trait->name, traits->name);
-	      SWFDEC_LOG ("  method: %u (override)", SWFDEC_ABC_BINDING_GET_ID (bind));
-	    } else {
-	      THROW (file, "The ABC data is corrupt, attempt to read out of bounds.");
-	    }
-
-	    /* try to find own trait */
-	    found = swfdec_abc_traits_get_trait (traits, trait->ns, trait->name);
-	    if (found) {
-	      /* FIXME: This is kinda (read: very) hacky */
-	      trait = (SwfdecAbcTrait *) found;
-	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_GETSET, 
-		  SWFDEC_ABC_BINDING_GET_ID (trait->type));
-	      SWFDEC_LOG ("  method: %u (reuse)", SWFDEC_ABC_BINDING_GET_ID (trait->type));
-	    } else if (bind == SWFDEC_ABC_BINDING_NONE) {
-	      trait->type = SWFDEC_ABC_BINDING_NEW (ttype, n_methods);
-	      SWFDEC_LOG ("  method: %u (new)", n_methods);
-	      n_methods += 2;
-	    } else {
-	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_BINDING_GET_TYPE (bind) | ttype,
-		  SWFDEC_ABC_BINDING_GET_ID (bind));
-	    }
-	    if (type == 2) {
-	      trait->default_index = method_id;
-	    } else {
-	      trait->default_type = method_id;
-	    }
-	  }
-	}
-        break;
-      default:
-	THROW (file, "Unsupported traits kind=%u.", type);
-    }
-
-    if (metadata) {
-      guint ignore, j, count;
-      READ_U30 (count, bits);
-  
-      SWFDEC_INFO ("parse metadata, in particular \"NeedsDxns\"");
-      for (j = 0; j < count; j++) {
-	READ_U30 (ignore, bits);
-      }
-    }
-  }
-
-  traits->n_slots = n_slots;
-  traits->n_methods = n_methods;
-
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_methods (SwfdecAbcFile *file, SwfdecBits *bits,
-    const GCallback *natives, guint n_natives)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  guint i;
-
-  READ_U30 (file->n_functions, bits);
-  SWFDEC_LOG ("%u methods", file->n_functions);
-  if (file->n_functions) {
-    gboolean param_names, optional, native;
-    file->functions = swfdec_as_context_try_new (context, SwfdecAbcFunction *, file->n_functions);
-    if (file->functions == NULL) {
-      file->n_functions = 0;
-      return FALSE;
-    }
-    for (i = 0; i < file->n_functions; i++) {
-      guint id, j, len;
-      SwfdecAbcFunction *fun = file->functions[i] = 
-	g_object_new (SWFDEC_TYPE_ABC_FUNCTION, "context", context, NULL);
-      fun->pool = file;
-      READ_U30 (len, bits);
-      SWFDEC_LOG ("  function %u:", i);
-      fun->args = swfdec_as_context_try_new (context, SwfdecAbcFunctionArgument, len + 1);
-      if (fun->args == NULL)
-	return FALSE;
-      fun->n_args = len;
-      fun->min_args = len;
-      READ_U30 (id, bits);
-      if (id == 0) {
-	fun->return_type = NULL;
-      } else if (id < file->n_multinames) {
-	fun->return_type = &file->multinames[id];
-      } else {
-	THROW (file, "Cpool index %u is out of range %u.", id, file->n_multinames);
-      }
-      SWFDEC_LOG ("    return type: %s", fun->return_type ? ((SwfdecAbcMultiname *) fun->return_type)->name : "void");
-      for (j = 1; j <= fun->n_args; j++) {
-	READ_U30 (id, bits);
-	if (id == 0) {
-	  fun->args[j].type = NULL;
-	} else if (id < file->n_multinames) {
-	  fun->args[j].type = &file->multinames[id];
-	} else {
-	  THROW (file, "Cpool index %u is out of range %u.", id, file->n_multinames);
-	}
-	SWFDEC_LOG ("    argument %u: type %s", j, fun->args[j].type ? ((SwfdecAbcMultiname *) fun->args[j].type)->name : "void");
-      }
-      READ_U30 (id, bits);
-      if (id > file->n_strings) {
-	THROW (file, "Cpool index %u is out of range %u.", id, file->n_strings);
-      } else if (id > 0) {
-	fun->name = file->strings[id];
-      }
-      param_names = swfdec_bits_getbit (bits);
-      fun->set_dxns = swfdec_bits_getbit (bits);
-      native = swfdec_bits_getbit (bits);
-      /* ignored = */ swfdec_bits_getbit (bits);
-      optional = swfdec_bits_getbit (bits);
-      fun->need_rest = swfdec_bits_getbit (bits);
-      fun->need_activation = swfdec_bits_getbit (bits);
-      fun->need_arguments = swfdec_bits_getbit (bits);
-      if (native) {
-
-	if (i >= n_natives) {
-	  SWFDEC_ERROR ("only %u native methods specified, but wanting index %u", n_natives, i);
-	} else {
-	  fun->native = natives[i];
-	}
-	if (fun->native == NULL) {
-	  SWFDEC_INFO ("no native for index %u", i);
-	}
-      }
-      if (optional) {
-	READ_U30 (len, bits);
-	if (len == 0 || len > fun->n_args)
-	  return FALSE;
-	fun->min_args -= len;
-	for (j = fun->min_args + 1; j <= fun->n_args; j++) {
-	  READ_U30 (id, bits);
-	  fun->args[j].default_index = id;
-	  fun->args[j].default_type = swfdec_bits_get_u8 (bits);
-	}
-      }
-      if (param_names) {
-	/* Tamarin doesn't parse this, so we must not error out here */
-	for (j = 1; j <= fun->n_args; j++) {
-	  id = swfdec_bits_get_vu32 (bits);
-	  if (id > 0 && id < file->n_strings)
-	    fun->args[j].name = file->strings[id];
-	}
-      }
-    }
-  }
-
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_skip_metadata (SwfdecAbcFile *file, SwfdecBits *bits)
-{
-  guint i, j, ignore, count, count2;
-
-  READ_U30 (count, bits);
-  for (i = 0; i < count; i++) {
-    READ_U30 (ignore, bits);
-    READ_U30 (count2, bits);
-    for (j = 0; j < count2; j++) {
-      READ_U30 (ignore, bits); /* key */
-      READ_U30 (ignore, bits); /* value */
-    }
-  }
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_instance (SwfdecAbcFile *file, guint instance_id, SwfdecBits *bits)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  gboolean protected_ns;
-  SwfdecAbcTraits *traits;
-  guint id, i, n;
-
-  SWFDEC_LOG ("instance: %u", instance_id);
-  traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
-  traits->pool = file;
-  if (!swfdec_abc_file_parse_qname (file, bits, &traits->ns, &traits->name))
-    return FALSE;
-  SWFDEC_LOG ("  name: %s::%s", traits->ns->uri, traits->name);
-  
-  READ_U30 (id, bits);
-  /* id == 0 means no base traits */
-  if (id >= file->n_multinames) {
-    THROW (file, "Cpool index %u is out of range %u.", id, file->n_multinames);
-  } else if (id > 0) {
-    SwfdecAbcTraits *base = swfdec_abc_global_get_traits_for_multiname (file->global,
-	&file->multinames[id]);
-    if (base == NULL)
-      THROW (file, "Class %s could not be found.", file->multinames[id].name);
-    if (base->final || 
-	(file->global->file != NULL && 
-	 (base == SWFDEC_ABC_CLASS_TRAITS (context) || base == SWFDEC_ABC_FUNCTION_TRAITS (context)))) {
-      THROW (file, "Class %s cannot extend final base class.", file->multinames[id].name);
-    }
-    if (base->interface || traits->interface) {
-      THROW (file, "Class %s cannot extend %s.", file->multinames[id].name, base->name);
-    }
-    traits->base = base;
-    SWFDEC_LOG ("  base: %s::%s", base->ns->uri, base->name);
-  } else {
-    SWFDEC_LOG ("  no base type");
-  }
-  /* reserved = */ swfdec_bits_getbits (bits, 4);
-  protected_ns = swfdec_bits_getbit (bits);
-  traits->interface = swfdec_bits_getbit (bits);
-  traits->final = swfdec_bits_getbit (bits);
-  traits->sealed = swfdec_bits_getbit (bits);
-  if (protected_ns) {
-    READ_U30 (id, bits);
-    if (id == 0) {
-      /* traits->protected_ns = NULL; */
-    } else if (id < file->n_namespaces) {
-      traits->protected_ns = file->namespaces[id];
-    } else if (id != 0) {
-      THROW (file, "Cpool index %u is out of range %u.", id, file->n_multinames);
-    }
-  }
-  READ_U30 (n, bits);
-  if (n > 0) {
-    SWFDEC_FIXME ("implement interface parsing");
-    for (i = 0; i < n; i++) {
-      READ_U30 (id, bits);
-    }
-  } 
-  if (!swfdec_abc_file_parse_method (file, bits, traits, NULL))
-    return FALSE;
-
-  if (!swfdec_abc_file_parse_traits (file, traits, bits))
-    return FALSE;
-  swfdec_abc_global_add_traits (file->global, traits);
-  file->instances[instance_id] = traits;
-
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_instances (SwfdecAbcFile *file, SwfdecBits *bits)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  guint i;
-
-  READ_U30 (file->n_classes, bits);
-  SWFDEC_LOG ("%u classes", file->n_classes);
-  if (file->n_classes) {
-    file->instances = swfdec_as_context_try_new (context, SwfdecAbcTraits *, file->n_classes);
-    file->classes = swfdec_as_context_try_new (context, SwfdecAbcTraits *, file->n_classes);
-    if (file->instances == NULL || file->classes == NULL) {
-      if (file->instances) {
-	swfdec_as_context_free (context, sizeof (SwfdecAbcFunction *) * file->n_classes, file->instances);
-	file->instances = NULL;
-      }
-      if (file->classes) {
-	swfdec_as_context_free (context, sizeof (SwfdecAbcFunction *) * file->n_classes, file->classes);
-	file->classes = NULL;
-      }
-      file->n_classes = 0;
-      return FALSE;
-    }
-    for (i = 0; i < file->n_classes; i++) {
-      if (!swfdec_abc_file_parse_instance (file, i, bits))
-	return FALSE;
-    }
-  }
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_classes (SwfdecAbcFile *file, SwfdecBits *bits)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  guint i;
-
-  if (file->n_classes) {
-    for (i = 0; i < file->n_classes; i++) {
-      SwfdecAbcTraits *traits;
-
-      SWFDEC_LOG ("class %u", i);
-      traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
-      traits->pool = file;
-
-      traits->ns = file->instances[i]->ns;
-      traits->name = swfdec_as_context_give_string (context,
-	  g_strconcat (file->instances[i]->name, "$", NULL));
-      traits->final = TRUE;
-      traits->sealed = FALSE;
-      if (SWFDEC_ABC_GLOBAL (context->global)->file)
-	traits->base = SWFDEC_ABC_CLASS_TRAITS (context);
-      else
-	traits->base = file->instances[SWFDEC_ABC_TYPE_CLASS];
-      g_assert (traits->base);
-
-      if (!swfdec_abc_file_parse_method (file, bits, traits, NULL))
-	return FALSE;
-
-      if (!swfdec_abc_file_parse_traits (file, traits, bits))
-	return FALSE;
-
-      traits->instance_traits = file->instances[i];
-      file->classes[i] = traits;
-    }
-  }
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_scripts (SwfdecAbcFile *file, SwfdecBits *bits)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  SwfdecAbcScript *script = NULL;
-  SwfdecAbcTraits *traits;
-  SwfdecAbcFunction *fun;
-  guint i, j, n_scripts;
-
-  READ_U30 (n_scripts, bits);
-  SWFDEC_LOG ("%u scripts ", n_scripts);
-  for (i = 0; i < n_scripts; i++) {
-    SWFDEC_LOG ("script %u", i);
-    traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
-    traits->pool = file;
-    traits->final = TRUE;
-    traits->ns = context->public_ns;
-    traits->name = SWFDEC_AS_STR_global;
-    if (SWFDEC_ABC_GLOBAL (context->global)->file)
-      traits->base = SWFDEC_ABC_OBJECT_TRAITS (context);
-    else
-      traits->base = file->instances[SWFDEC_ABC_TYPE_OBJECT];
-    if (!swfdec_abc_file_parse_method (file, bits, traits, &fun))
-      return FALSE;
-    traits->construct = fun;
-    if (!swfdec_abc_file_parse_traits (file, traits, bits))
-      return FALSE;
-    script = g_object_new (SWFDEC_TYPE_ABC_SCRIPT, "context", context, NULL);
-    script->traits = traits;
-    for (j = 0; j < traits->n_traits; j++) {
-      SwfdecAbcTrait *trait = &traits->traits[j];
-      if (trait->type == SWFDEC_ABC_TRAIT_NONE)
-	continue;
-      swfdec_abc_global_add_script (file->global, trait->ns, trait->name, script, 
-	  i + 1 == n_scripts);
-    }
-  }
-  if (script == 0)
-    THROW (file, "No entry point was found.");
-  file->main = script;
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse_bodies (SwfdecAbcFile *file, SwfdecBits *bits)
-{
-  SwfdecAsContext *context = swfdec_gc_object_get_context (file);
-  SwfdecAbcTraits *traits;
-  SwfdecAbcFunction *fun;
-  guint i, j, max_scope, min_scope, n_bodies, size;
-
-  READ_U30 (n_bodies, bits);
-  SWFDEC_LOG ("%u bodies", n_bodies);
-  for (i = 0; i < n_bodies; i++) {
-    SWFDEC_LOG ("body %u", i);
-    if (!swfdec_abc_file_parse_method (file, bits, NULL, &fun))
-      return FALSE;
-    if (swfdec_abc_function_is_native (fun))
-      THROW (file, "Native method %"G_GSIZE_FORMAT" has illegal method body.", fun - file->functions[0]);
-    if (fun->bound_traits && fun->bound_traits->interface)
-      THROW (file, "Interface method %"G_GSIZE_FORMAT" has illegal method body.", fun - file->functions[0]);
-    if (fun->code != NULL)
-      THROW (file, "Method %"G_GSIZE_FORMAT" has a duplicate method body.", fun - file->functions[0]);
-
-    READ_U30 (fun->n_stack, bits);
-    SWFDEC_LOG ("  stack: %u", fun->n_stack);
-    READ_U30 (fun->n_locals, bits);
-    if (fun->n_args >= fun->n_locals)
-      THROW (file, "The ABC data is corrupt, attempt to read out of bounds.");
-    SWFDEC_LOG ("  locals: %u", fun->n_locals);
-    READ_U30 (min_scope, bits);
-    READ_U30 (max_scope, bits);
-    if (min_scope > max_scope)
-      THROW (file, "The ABC data is corrupt, attempt to read out of bounds.");
-    fun->n_scope = max_scope - min_scope;
-    SWFDEC_LOG ("  scope: %u (%u - %u)", fun->n_scope, min_scope, max_scope);
-    READ_U30 (size, bits);
-    if (size == 0)
-      THROW (file, "Invalid code_length=0.");
-    SWFDEC_LOG ("  code: %u bytes", size);
-    fun->code = swfdec_bits_get_buffer (bits, size);
-    if (fun->code == NULL)
-      THROW (file, "The ABC data is corrupt, attempt to read out of bounds.");
-
-    READ_U30 (fun->n_exceptions, bits);
-    SWFDEC_LOG ("  exceptions: %u", fun->n_exceptions);
-    if (fun->n_exceptions) {
-      fun->exceptions = swfdec_as_context_try_new (context, SwfdecAbcException, fun->n_exceptions);
-      if (fun->exceptions == NULL) {
-	fun->n_exceptions = 0;
-	return FALSE;
-      }
-      for (j = 0; j < fun->n_exceptions; j++) {
-	SwfdecAbcException *ex = &fun->exceptions[j];
-	READ_U30 (ex->from, bits);
-	READ_U30 (ex->to, bits);
-	READ_U30 (ex->target, bits);
-	READ_U30 (ex->type, bits);
-	READ_U30 (ex->var, bits);
-      }
-    }
-
-    traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
-    traits->pool = file;
-    traits->final = TRUE;
-    traits->ns = context->public_ns;
-    traits->name = SWFDEC_AS_STR_EMPTY;
-    if (SWFDEC_ABC_GLOBAL (context->global)->file)
-      traits->base = SWFDEC_ABC_OBJECT_TRAITS (context);
-    else
-      traits->base = file->instances[SWFDEC_ABC_TYPE_OBJECT];
-    if (!swfdec_abc_file_parse_traits (file, traits, bits))
-      return FALSE;
-    fun->activation = traits;
-  }
-  return TRUE;
-}
-
-static gboolean
-swfdec_abc_file_parse (SwfdecAbcFile *file, SwfdecBits *bits,
-    const GCallback *natives, guint n_natives)
-{
-  return swfdec_abc_file_parse_constants (file, bits) &&
-      swfdec_abc_file_parse_methods (file, bits, natives, n_natives) &&
-      swfdec_abc_file_skip_metadata (file, bits) &&
-      swfdec_abc_file_parse_instances (file, bits) &&
-      swfdec_abc_file_parse_classes (file, bits) &&
-      swfdec_abc_file_parse_scripts (file, bits) &&
-      swfdec_abc_file_parse_bodies (file, bits);
-}
-
-SwfdecAbcFile *
-swfdec_abc_file_new (SwfdecAsContext *context, SwfdecBits *bits)
-{
-  return swfdec_abc_file_new_trusted (context, bits, NULL, 0);
-}
-
-SwfdecAbcFile *
-swfdec_abc_file_new_trusted (SwfdecAsContext *context, SwfdecBits *bits,
-    const GCallback *natives, guint n_natives)
-{
-  SwfdecAbcFile *file;
-  guint major, minor;
-
-  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
-  g_return_val_if_fail (SWFDEC_IS_ABC_GLOBAL (context->global), NULL);
-  g_return_val_if_fail (bits != NULL, NULL);
-
-  file = g_object_new (SWFDEC_TYPE_ABC_FILE, "context", context, NULL);
-  file->global = SWFDEC_ABC_GLOBAL (context->global);
-
-  minor = swfdec_bits_get_u16 (bits);
-  major = swfdec_bits_get_u16 (bits);
-  SWFDEC_LOG ("  major version: %u", major);
-  SWFDEC_LOG ("  minor version: %u", minor);
-  if (major == 46 && minor == 16) {
-    if (!swfdec_abc_file_parse (file, bits, natives, n_natives)) {
-      swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_VERIFY_ERROR,
-	  "The ABC data is corrupt, attempt to read out of bounds.");
-      return NULL;
-    }
-  } else {
-    swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_VERIFY_ERROR,
-	"Not an ABC file.  major_version=%u minor_version=%u.", major, minor);
-    return NULL;
-  }
-  
-//#define SWFDEC_PRINT_STUBS
-#ifdef SWFDEC_PRINT_STUBS
-  {
-    guint i;
-
-    if (SWFDEC_ABC_GLOBAL (context->global)->file == NULL)
-      SWFDEC_ABC_GLOBAL (context->global)->file = file;
-    
-    /* update machine types */
-    SWFDEC_ABC_BOOLEAN_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
-    SWFDEC_ABC_INT_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
-    SWFDEC_ABC_UINT_TRAITS (context)->machine_type = SWFDEC_ABC_UINT;
-    SWFDEC_ABC_NUMBER_TRAITS (context)->machine_type = SWFDEC_ABC_DOUBLE;
-    SWFDEC_ABC_STRING_TRAITS (context)->machine_type = SWFDEC_ABC_STRING;
-
-    g_print ("missing implementations:\n");
-    for (i = 0; i < file->n_functions; i++) {
-      SwfdecAbcFunction *fun = file->functions[i];
-      char *name;
-      if (fun->code != NULL)
-	continue;
-      /* This is why we can't print this stuff by default: We need to resolve
-       * the function, which could throw */
-      if (!swfdec_abc_function_resolve (fun) ||
-	  (fun->bound_traits != NULL && !swfdec_abc_traits_resolve (fun->bound_traits))) {
-	g_assert_not_reached ();
-      }
-      name = swfdec_abc_function_describe (fun);
-      g_print ("%s %s\n", fun->native == NULL ? "XXX" : "   ", name);
-      g_free (name);
-      }
-  }
-#endif
-
-  return file;
-}
-
-gboolean
-swfdec_abc_file_get_constant (SwfdecAbcFile *pool, SwfdecAsValue *value, 
-    guint type, guint id)
-{
-  g_return_val_if_fail (SWFDEC_IS_ABC_FILE (pool), FALSE);
-  g_return_val_if_fail (value != NULL, FALSE);
-
-  switch (type) {
-    case SWFDEC_ABC_CONST_UNDEFINED:
-      SWFDEC_AS_VALUE_SET_UNDEFINED (value);
-      break;
-    case SWFDEC_ABC_CONST_STRING:
-      if (id >= pool->n_strings)
-	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_strings);
-      SWFDEC_AS_VALUE_SET_STRING (value, pool->strings[id]);
-      break;
-    case SWFDEC_ABC_CONST_INT:
-      if (id >= pool->n_ints)
-	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_ints);
-      SWFDEC_AS_VALUE_SET_INT (value, pool->ints[id]);
-      break;
-    case SWFDEC_ABC_CONST_UINT:
-      if (id >= pool->n_uints)
-	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_uints);
-      SWFDEC_AS_VALUE_SET_NUMBER (value, pool->uints[id]);
-      break;
-    case SWFDEC_ABC_CONST_DOUBLE:
-      if (id >= pool->n_doubles)
-	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_doubles);
-      SWFDEC_AS_VALUE_SET_NUMBER (value, pool->doubles[id]);
-      break;
-    case SWFDEC_ABC_CONST_FALSE:
-      SWFDEC_AS_VALUE_SET_BOOLEAN (value, FALSE);
-      break;
-    case SWFDEC_ABC_CONST_TRUE:
-      SWFDEC_AS_VALUE_SET_BOOLEAN (value, TRUE);
-      break;
-    case SWFDEC_ABC_CONST_NULL:
-      SWFDEC_AS_VALUE_SET_NULL (value);
-      break;
-    case SWFDEC_ABC_CONST_PRIVATE_NAMESPACE:
-    case SWFDEC_ABC_CONST_NAMESPACE:
-    case SWFDEC_ABC_CONST_PACKAGE_NAMESPACE:
-    case SWFDEC_ABC_CONST_INTERNAL_NAMESPACE:
-    case SWFDEC_ABC_CONST_PROTECTED_NAMESPACE:
-    case SWFDEC_ABC_CONST_EXPLICIT_NAMESPACE:
-    case SWFDEC_ABC_CONST_STATIC_PROTECTED_NAMESPACE:
-      if (id >= pool->n_namespaces)
-	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_namespaces);
-      SWFDEC_AS_VALUE_SET_NAMESPACE (value, pool->namespaces[id]);
-      break;
-    default:
-      THROW (pool, "Illegal default value for type %s.", "FIXME");
-  }
-  return TRUE;
-}
diff --git a/swfdec/swfdec_abc_file.h b/swfdec/swfdec_abc_file.h
deleted file mode 100644
index 776bc38..0000000
--- a/swfdec/swfdec_abc_file.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* Swfdec
- * Copyright (C) 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
- * 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_ABC_FILE_H_
-#define _SWFDEC_ABC_FILE_H_
-
-#include <swfdec/swfdec_abc_global.h>
-#include <swfdec/swfdec_abc_multiname.h>
-#include <swfdec/swfdec_abc_namespace.h>
-#include <swfdec/swfdec_abc_ns_set.h>
-#include <swfdec/swfdec_abc_types.h>
-#include <swfdec/swfdec_bits.h>
-#include <swfdec/swfdec_gc_object.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
-  SWFDEC_ABC_CONST_UNDEFINED = 0,
-  SWFDEC_ABC_CONST_STRING = 1,
-  SWFDEC_ABC_CONST_INT = 3,
-  SWFDEC_ABC_CONST_UINT = 4,
-  SWFDEC_ABC_CONST_PRIVATE_NAMESPACE = 5,
-  SWFDEC_ABC_CONST_DOUBLE = 6,
-  SWFDEC_ABC_CONST_NAMESPACE = 8,
-  SWFDEC_ABC_CONST_FALSE = 10,
-  SWFDEC_ABC_CONST_TRUE = 11,
-  SWFDEC_ABC_CONST_NULL = 12,
-  SWFDEC_ABC_CONST_PACKAGE_NAMESPACE = 22,
-  SWFDEC_ABC_CONST_INTERNAL_NAMESPACE = 23,
-  SWFDEC_ABC_CONST_PROTECTED_NAMESPACE = 24,
-  SWFDEC_ABC_CONST_EXPLICIT_NAMESPACE = 25,
-  SWFDEC_ABC_CONST_STATIC_PROTECTED_NAMESPACE = 26
-} SwfdecAbcConstant;
-
-//typedef struct _SwfdecAbcFile SwfdecAbcFile;
-typedef struct _SwfdecAbcFileClass SwfdecAbcFileClass;
-
-#define SWFDEC_TYPE_ABC_FILE                    (swfdec_abc_file_get_type())
-#define SWFDEC_IS_ABC_FILE(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_ABC_FILE))
-#define SWFDEC_IS_ABC_FILE_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_ABC_FILE))
-#define SWFDEC_ABC_FILE(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_ABC_FILE, SwfdecAbcFile))
-#define SWFDEC_ABC_FILE_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_ABC_FILE, SwfdecAbcFileClass))
-#define SWFDEC_ABC_FILE_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_ABC_FILE, SwfdecAbcFileClass))
-
-struct _SwfdecAbcFile {
-  SwfdecGcObject	object;
-
-  SwfdecAbcGlobal *	global;		/* the global object we belong to */
-
-  int *			ints;		/* all integer values in the file */
-  guint			n_ints;		/* number of integers */
-  guint *		uints;		/* all unsigned integer values in the file */
-  guint			n_uints;	/* number of unsigned integers */
-  double *		doubles;	/* all double values in the file */
-  guint			n_doubles;	/* number of doubles */
-  const char **		strings;	/* all string values in the file */
-  guint			n_strings;	/* number of strings */
-  SwfdecAbcNamespace **	namespaces;	/* all the namespaces in use */
-  guint			n_namespaces;	/* number of namespaces */
-  SwfdecAbcNsSet **	nssets;		/* all the namespace sets in use */
-  guint			n_nssets;	/* number of namespace sets */
-  SwfdecAbcMultiname *	multinames;   	/* all the multinames in use */
-  guint			n_multinames;	/* number of multinames */
-  SwfdecAbcFunction **	functions;   	/* all the functions defined */
-  guint			n_functions;	/* number of functions */
-  SwfdecAbcTraits **	instances;   	/* instance infos for the defined classes */
-  SwfdecAbcTraits **	classes;   	/* all the classes defined */
-  guint			n_classes;   	/* number of classes */
-  SwfdecAbcScript *	main;		/* main script */
-};
-
-struct _SwfdecAbcFileClass {
-  SwfdecGcObjectClass	object_class;
-};
-
-GType		swfdec_abc_file_get_type	(void);
-
-SwfdecAbcFile *	swfdec_abc_file_new		(SwfdecAsContext *	context,
-						 SwfdecBits *		bits);
-SwfdecAbcFile *	swfdec_abc_file_new_trusted	(SwfdecAsContext *	context,
-						 SwfdecBits *		bits,
-						 const GCallback *	natives,
-						 guint			n_natives);
-
-gboolean	swfdec_abc_file_get_constant	(SwfdecAbcFile *	pool,
-						 SwfdecAsValue *	value,
-						 guint			type,
-						 guint			id);
-
-
-G_END_DECLS
-#endif
diff --git a/swfdec/swfdec_abc_function.c b/swfdec/swfdec_abc_function.c
index 9c4a2c6..d0e58d6 100644
--- a/swfdec/swfdec_abc_function.c
+++ b/swfdec/swfdec_abc_function.c
@@ -23,7 +23,7 @@
 
 #include "swfdec_abc_function.h"
 
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_global.h"
 #include "swfdec_abc_internal.h"
 #include "swfdec_abc_interpret.h"
@@ -327,7 +327,7 @@ swfdec_abc_function_resolve (SwfdecAbcFunction *fun)
     if (fun->args[i].default_index == 0) {
       SWFDEC_AS_VALUE_SET_UNDEFINED (&fun->args[i].default_value);
     } else {
-      if (!swfdec_abc_file_get_constant (fun->pool, &fun->args[i].default_value,
+      if (!swfdec_abc_pool_get_constant (fun->pool, &fun->args[i].default_value,
 	    fun->args[i].default_type, fun->args[i].default_index))
 	return FALSE;
     }
diff --git a/swfdec/swfdec_abc_function.h b/swfdec/swfdec_abc_function.h
index 696b71d..7b7c9d6 100644
--- a/swfdec/swfdec_abc_function.h
+++ b/swfdec/swfdec_abc_function.h
@@ -66,7 +66,7 @@ struct _SwfdecAbcException {
 struct _SwfdecAbcFunction {
   SwfdecGcObject	object;
 
-  SwfdecAbcFile *	pool;			/* pool that spawned us */
+  SwfdecAbcPool *	pool;			/* pool that spawned us */
   const char *		name;			/* gc'd name of the function or NULL if unnamed */
   gboolean		verified:1;		/* function body has been verified */
   gboolean		resolved:1;		/* function arguments and return type have been resolved */
diff --git a/swfdec/swfdec_abc_global.c b/swfdec/swfdec_abc_global.c
index 1dd8c29..afcea5f 100644
--- a/swfdec/swfdec_abc_global.c
+++ b/swfdec/swfdec_abc_global.c
@@ -28,7 +28,7 @@
 #include <math.h>
 
 #include "swfdec_abc_class.h"
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_function.h"
 #include "swfdec_abc_initialize.h"
 #include "swfdec_abc_internal.h"
@@ -91,13 +91,13 @@ swfdec_abc_global_constructor (GType type, guint n_construct_properties,
 
   /* init default pool */
   swfdec_bits_init_data (&bits, swfdec_abc_initialize, sizeof (swfdec_abc_initialize));
-  global->file = swfdec_abc_file_new_trusted (context, &bits, 
+  global->pool = swfdec_abc_pool_new_trusted (context, &bits, 
       swfdec_abc_natives, G_N_ELEMENTS (swfdec_abc_natives));
   /* must work and not throw exceptions */
-  g_assert (global->file);
+  g_assert (global->pool);
 
   /* set proper traits here */
-  traits = global->file->main->traits;
+  traits = global->pool->main->traits;
   if (!swfdec_abc_traits_resolve (traits)) {
     g_assert_not_reached ();
   }
@@ -116,7 +116,7 @@ swfdec_abc_global_constructor (GType type, guint n_construct_properties,
   SWFDEC_ABC_STRING_TRAITS (context)->machine_type = SWFDEC_ABC_STRING;
 
   /* run main script */
-  global->file->main->global = SWFDEC_ABC_OBJECT (global);
+  global->pool->main->global = SWFDEC_ABC_OBJECT (global);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (global));
   swfdec_abc_function_call (traits->construct, NULL, 0, &val, &val);
   return object;
@@ -296,10 +296,10 @@ SwfdecAbcTraits *
 swfdec_abc_global_get_builtin_traits (SwfdecAbcGlobal *global, guint id)
 {
   g_return_val_if_fail (SWFDEC_IS_ABC_GLOBAL (global), NULL);
-  g_return_val_if_fail (global->file, NULL);
+  g_return_val_if_fail (global->pool, NULL);
   g_return_val_if_fail (id < SWFDEC_ABC_N_TYPES, NULL);
 
-  return global->file->instances[id];
+  return global->pool->instances[id];
 }
 
 SwfdecAbcClass *
@@ -310,10 +310,10 @@ swfdec_abc_global_get_builtin_class (SwfdecAbcGlobal *global, guint id)
   SwfdecAsValue val;
 
   g_return_val_if_fail (SWFDEC_IS_ABC_GLOBAL (global), NULL);
-  g_return_val_if_fail (global->file, NULL);
+  g_return_val_if_fail (global->pool, NULL);
   g_return_val_if_fail (id < SWFDEC_ABC_N_TYPES, NULL);
 
-  traits = global->file->instances[id];
+  traits = global->pool->instances[id];
 
   swfdec_abc_multiname_init (&mn, traits->name, traits->ns, NULL);
   SWFDEC_AS_VALUE_SET_OBJECT (&val, SWFDEC_AS_OBJECT (global));
diff --git a/swfdec/swfdec_abc_global.h b/swfdec/swfdec_abc_global.h
index 613fb17..40305f3 100644
--- a/swfdec/swfdec_abc_global.h
+++ b/swfdec/swfdec_abc_global.h
@@ -108,7 +108,7 @@ typedef struct _SwfdecAbcGlobalClass SwfdecAbcGlobalClass;
 struct _SwfdecAbcGlobal {
   SwfdecAbcObject	object;
 
-  SwfdecAbcFile	*	file;		/* file that read the default objects */
+  SwfdecAbcPool	*	pool;		/* file that read the default objects */
   SwfdecAbcTraits *	void_traits;	/* the void traits */
   SwfdecAbcTraits *	null_traits;	/* the null traits */
   SwfdecAbcClass *	classes[SWFDEC_ABC_N_TYPES];	/* NULL or resolved Class objects */
diff --git a/swfdec/swfdec_abc_interpret.c b/swfdec/swfdec_abc_interpret.c
index af2d4b6..a363488 100644
--- a/swfdec/swfdec_abc_interpret.c
+++ b/swfdec/swfdec_abc_interpret.c
@@ -26,7 +26,7 @@
 #include <math.h>
 
 #include "swfdec_abc_class.h"
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_function.h"
 #include "swfdec_abc_internal.h"
 #include "swfdec_abc_scope_chain.h"
@@ -562,7 +562,7 @@ swfdec_abc_interpret (SwfdecAbcFunction *fun, SwfdecAbcScopeChain *outer_scope)
   guint i, opcode;
   /* used in interpretation switch */
   SwfdecAbcMultiname mn;
-  SwfdecAbcFile *pool;
+  SwfdecAbcPool *pool;
   SwfdecAsValue *val;
 
   g_return_val_if_fail (SWFDEC_IS_ABC_FUNCTION (fun), FALSE);
diff --git a/swfdec/swfdec_abc_pool.c b/swfdec/swfdec_abc_pool.c
new file mode 100644
index 0000000..dbd9422
--- /dev/null
+++ b/swfdec/swfdec_abc_pool.c
@@ -0,0 +1,1163 @@
+/* Swfdec
+ * Copyright (C) 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
+ * 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 "swfdec_abc_pool.h"
+
+#include <math.h>
+
+#include "swfdec_abc_function.h"
+#include "swfdec_abc_internal.h"
+#include "swfdec_abc_script.h"
+#include "swfdec_abc_traits.h"
+#include "swfdec_as_frame.h" /* default stub */
+#include "swfdec_as_strings.h"
+#include "swfdec_debug.h"
+
+/*** SWFDEC_ABC_POOL ***/
+
+G_DEFINE_TYPE (SwfdecAbcPool, swfdec_abc_pool, SWFDEC_TYPE_GC_OBJECT)
+
+static void
+swfdec_abc_pool_dispose (GObject *object)
+{
+  SwfdecAbcPool *pool = SWFDEC_ABC_POOL (object);
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+
+  if (pool->n_ints) {
+    swfdec_as_context_free (context, pool->n_ints * sizeof (int), pool->ints);
+  }
+  if (pool->n_uints) {
+    swfdec_as_context_free (context, pool->n_uints * sizeof (guint), pool->uints);
+  }
+  if (pool->n_doubles) {
+    swfdec_as_context_free (context, pool->n_doubles * sizeof (double), pool->doubles);
+  }
+  if (pool->n_strings) {
+    swfdec_as_context_free (context, pool->n_strings * sizeof (const char *), pool->strings);
+  }
+  if (pool->n_namespaces) {
+    swfdec_as_context_free (context, pool->n_namespaces * sizeof (SwfdecAbcNamespace *),
+	pool->namespaces);
+  }
+  if (pool->n_nssets) {
+    guint i;
+    for (i = 0; i < pool->n_nssets; i++) {
+      swfdec_abc_ns_set_free (pool->nssets[i]);
+    }
+    swfdec_as_context_free (context, pool->n_nssets * sizeof (SwfdecAbcNsSet *),
+	pool->nssets);
+  }
+  if (pool->n_multinames) {
+    swfdec_as_context_free (context, pool->n_multinames * sizeof (SwfdecAbcMultiname),
+	pool->multinames);
+  }
+  if (pool->n_functions) {
+    swfdec_as_context_free (context, pool->n_functions * sizeof (SwfdecAbcFunction *),
+	pool->functions);
+  }
+  if (pool->n_classes) {
+    swfdec_as_context_free (context, pool->n_classes * sizeof (SwfdecAbcFunction *),
+	pool->instances);
+    swfdec_as_context_free (context, pool->n_classes * sizeof (SwfdecAbcFunction *),
+	pool->classes);
+  }
+
+  G_OBJECT_CLASS (swfdec_abc_pool_parent_class)->dispose (object);
+}
+
+static void
+swfdec_abc_pool_mark (SwfdecGcObject *object)
+{
+  SwfdecAbcPool *pool = SWFDEC_ABC_POOL (object);
+  guint i;
+
+  for (i = 0; i < pool->n_strings; i++) {
+    swfdec_as_string_mark (pool->strings[i]);
+  }
+  for (i = 1; i < pool->n_namespaces; i++) {
+    swfdec_gc_object_mark (pool->namespaces[i]);
+  }
+  for (i = 1; i < pool->n_functions; i++) {
+    if (pool->functions[i])
+      swfdec_gc_object_mark (pool->functions[i]);
+  }
+  for (i = 1; i < pool->n_classes; i++) {
+    if (pool->classes[i])
+      swfdec_gc_object_mark (pool->classes[i]);
+  }
+
+  if (pool->main)
+    swfdec_gc_object_mark (pool->main);
+
+  SWFDEC_GC_OBJECT_CLASS (swfdec_abc_pool_parent_class)->mark (object);
+}
+
+static void
+swfdec_abc_pool_class_init (SwfdecAbcPoolClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  SwfdecGcObjectClass *gc_class = SWFDEC_GC_OBJECT_CLASS (klass);
+
+  object_class->dispose = swfdec_abc_pool_dispose;
+
+  gc_class->mark = swfdec_abc_pool_mark;
+}
+
+static void
+swfdec_abc_pool_init (SwfdecAbcPool *date)
+{
+}
+
+/*** PARSING ***/
+
+#define READ_U30(x, bits) G_STMT_START{ \
+  x = swfdec_bits_get_vu32 (bits); \
+  if (x >= (1 << 30)) { \
+    SWFDEC_ERROR ("invalid U30 value %u\n", x); \
+    return FALSE; \
+  } \
+}G_STMT_END;
+#define THROW(pool, ...) G_STMT_START{ \
+  swfdec_as_context_throw_abc (swfdec_gc_object_get_context (pool), \
+      SWFDEC_ABC_TYPE_VERIFY_ERROR, __VA_ARGS__); \
+  return FALSE; \
+}G_STMT_END
+
+static gboolean
+swfdec_abc_pool_parse_qname (SwfdecAbcPool *pool, SwfdecBits *bits, SwfdecAbcNamespace **ns, const char **name)
+{
+  SwfdecAbcMultiname *mn;
+  guint id;
+
+  READ_U30 (id, bits);
+  if (id == 0 || id >= pool->n_multinames)
+    THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_multinames);
+  mn = &pool->multinames[id];
+  if (!swfdec_abc_multiname_is_qualified (mn))
+    THROW (pool, "Cpool entry %u is wrong type.", id);
+
+  *ns = mn->ns;
+  *name = mn->name;
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_constants (SwfdecAbcPool *pool, SwfdecBits *bits)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  guint i;
+
+  SWFDEC_LOG ("parsing ABC block");
+  /* read all integers */
+  READ_U30 (pool->n_ints, bits);
+  SWFDEC_LOG ("%u integers", pool->n_ints);
+  if (pool->n_ints) {
+    pool->ints = swfdec_as_context_try_new (context, int, pool->n_ints);
+    if (pool->ints == NULL) {
+      pool->n_ints = 0;
+      return FALSE;
+    }
+    for (i = 1; i < pool->n_ints && swfdec_bits_left (bits); i++) {
+      pool->ints[i] = swfdec_bits_get_vs32 (bits);
+      SWFDEC_LOG ("  int %u: %d", i, pool->ints[i]);
+    }
+  }
+
+  /* read all unsigned integers */
+  READ_U30 (pool->n_uints, bits);
+  SWFDEC_LOG ("%u unsigned integers", pool->n_uints);
+  if (pool->n_uints) {
+    pool->uints = swfdec_as_context_try_new (context, guint, pool->n_uints);
+    if (pool->uints == NULL) {
+      pool->n_uints = 0;
+      return FALSE;
+    }
+    for (i = 1; i < pool->n_uints && swfdec_bits_left (bits); i++) {
+      pool->uints[i] = swfdec_bits_get_vu32 (bits);
+      SWFDEC_LOG ("  uint %u: %u", i, pool->uints[i]);
+    }
+  }
+
+  /* read all doubles */
+  READ_U30 (pool->n_doubles, bits);
+  SWFDEC_LOG ("%u doubles", pool->n_doubles);
+  if (pool->n_doubles) {
+    pool->doubles = swfdec_as_context_try_new (context, double, pool->n_doubles);
+    if (pool->doubles == NULL) {
+      pool->n_doubles = 0;
+      return FALSE;
+    }
+    pool->doubles[0] = NAN;
+    for (i = 1; i < pool->n_doubles && swfdec_bits_left (bits); i++) {
+      pool->doubles[i] = swfdec_bits_get_ldouble (bits);
+      SWFDEC_LOG ("  double %u: %g", i, pool->doubles[i]);
+    }
+  }
+
+  /* read all strings */
+  READ_U30 (pool->n_strings, bits);
+  SWFDEC_LOG ("%u strings", pool->n_strings);
+  if (pool->n_strings) {
+    pool->strings = swfdec_as_context_try_new (context, const char *, pool->n_strings);
+    if (pool->strings == NULL) {
+      pool->n_strings = 0;
+      return FALSE;
+    }
+    for (i = 1; i < pool->n_strings; i++) {
+      guint len;
+      char *s;
+      READ_U30 (len, bits);
+      s = swfdec_bits_get_string_length (bits, len, 9);
+      if (s == NULL)
+	return FALSE;
+      pool->strings[i] = swfdec_as_context_give_string (context, s);
+      SWFDEC_LOG ("  string %u: %s", i, pool->strings[i]);
+    }
+  }
+
+  /* read all namespaces */
+  READ_U30 (pool->n_namespaces, bits);
+  SWFDEC_LOG ("%u namespaces", pool->n_namespaces);
+  if (pool->n_namespaces) {
+    pool->namespaces = swfdec_as_context_try_new (context, SwfdecAbcNamespace *, pool->n_namespaces);
+    if (pool->namespaces == NULL) {
+      pool->n_namespaces = 0;
+      return FALSE;
+    }
+    for (i = 1; i < pool->n_namespaces; i++) {
+      SwfdecAbcNamespaceType type;
+      guint id;
+      switch (swfdec_bits_get_u8 (bits)) {
+	case SWFDEC_ABC_CONST_PRIVATE_NAMESPACE:
+	  type = SWFDEC_ABC_NAMESPACE_PRIVATE;
+	  break;
+	case SWFDEC_ABC_CONST_NAMESPACE:
+	case SWFDEC_ABC_CONST_PACKAGE_NAMESPACE:
+	  type = SWFDEC_ABC_NAMESPACE_PUBLIC;
+	  break;
+	case SWFDEC_ABC_CONST_INTERNAL_NAMESPACE:
+	  type = SWFDEC_ABC_NAMESPACE_PACKAGE;
+	  break;
+	case SWFDEC_ABC_CONST_PROTECTED_NAMESPACE:
+	  type = SWFDEC_ABC_NAMESPACE_PROTECTED;
+	  break;
+	case SWFDEC_ABC_CONST_EXPLICIT_NAMESPACE:
+	  type = SWFDEC_ABC_NAMESPACE_EXPLICIT;
+	  break;
+	case SWFDEC_ABC_CONST_STATIC_PROTECTED_NAMESPACE:
+	  type = SWFDEC_ABC_NAMESPACE_STATIC_PROTECTED;
+	  break;
+	default:
+	  THROW (pool, "Cpool entry %u is wrong type.", i);
+      }
+      READ_U30 (id, bits);
+      if (id == 0) {
+	SWFDEC_LOG ("  namespace %u: undefined", i);
+	pool->namespaces[i] = (type == SWFDEC_ABC_NAMESPACE_PRIVATE ? 
+	    swfdec_abc_namespace_new : swfdec_as_context_get_namespace) (context,
+	    type, NULL, SWFDEC_AS_STR_undefined);
+      } else if (id < pool->n_strings) {
+	SWFDEC_LOG ("  namespace %u: %s", i, pool->strings[id]);
+	pool->namespaces[i] = (type == SWFDEC_ABC_NAMESPACE_PRIVATE ? 
+	    swfdec_abc_namespace_new : swfdec_as_context_get_namespace) (context,
+	    type, NULL, pool->strings[id]);
+      } else {
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_strings);
+      }
+    }
+  }
+
+  /* read all namespace sets */
+  READ_U30 (pool->n_nssets, bits);
+  SWFDEC_LOG ("%u namespace sets", pool->n_nssets);
+  if (pool->n_nssets) {
+    pool->nssets = swfdec_as_context_try_new (context, SwfdecAbcNsSet *, pool->n_nssets);
+    if (pool->nssets == NULL) {
+      pool->n_nssets = 0;
+      return FALSE;
+    }
+    for (i = 0; i < pool->n_nssets; i++) {
+      pool->nssets[i] = swfdec_abc_ns_set_new ();
+    }
+    for (i = 1; i < pool->n_nssets; i++) {
+      guint j, len;
+      READ_U30 (len, bits);
+      for (j = 0; j < len; j++) {
+	guint ns;
+	READ_U30 (ns, bits);
+	if (ns == 0 || ns >= pool->n_namespaces)
+	  return FALSE;
+	swfdec_abc_ns_set_add (pool->nssets[i], pool->namespaces[ns]);
+      }
+      SWFDEC_LOG ("  ns set %u: %u namespaces", i, len);
+    }
+  }
+
+  /* read all multinames */
+  READ_U30 (pool->n_multinames, bits);
+  SWFDEC_LOG ("%u multinames", pool->n_multinames);
+  if (pool->n_multinames) {
+    guint nsid, nameid;
+    pool->multinames = swfdec_as_context_try_new (context, SwfdecAbcMultiname, pool->n_multinames);
+    if (pool->multinames == NULL) {
+      pool->n_multinames = 0;
+      return FALSE;
+    }
+    for (i = 1; i < pool->n_multinames; i++) {
+      switch (swfdec_bits_get_u8 (bits)) {
+	case 0x0D:
+	  SWFDEC_FIXME ("implement attributes");
+	case 0x07:
+	  READ_U30 (nsid, bits);
+	  if (nsid >= pool->n_namespaces)
+	    THROW (pool, "Cpool index %u is out of range %u.", nsid, pool->n_namespaces);
+	  READ_U30 (nameid, bits);
+	  if (nameid >= pool->n_strings)
+	    THROW (pool, "Cpool index %u is out of range %u.", nameid, pool->n_strings);
+	  swfdec_abc_multiname_init (&pool->multinames[i],
+	      nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid],
+	      nsid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->namespaces[nsid],
+	      NULL);
+	  break;
+	case 0x10:
+	  SWFDEC_FIXME ("implement attributes");
+	case 0x0F:
+	  READ_U30 (nameid, bits);
+	  if (nameid >= pool->n_strings)
+	    THROW (pool, "Cpool index %u is out of range %u.", nameid, pool->n_strings);
+	  swfdec_abc_multiname_init (&pool->multinames[i],
+	      nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid],
+	      NULL, NULL);
+	  break;
+	case 0x12:
+	  SWFDEC_FIXME ("implement attributes");
+	case 0x11:
+	  swfdec_abc_multiname_init (&pool->multinames[i],
+	      NULL, NULL, NULL);
+	  break;
+	case 0x0E:
+	  SWFDEC_FIXME ("implement attributes");
+	case 0x09:
+	  READ_U30 (nameid, bits);
+	  if (nameid >= pool->n_strings)
+	    THROW (pool, "Cpool index %u is out of range %u.", nameid, pool->n_strings);
+	  READ_U30 (nsid, bits);
+	  if (nsid >= pool->n_nssets)
+	    THROW (pool, "Cpool index %u is out of range %u.", nsid, pool->n_nssets);
+	  swfdec_abc_multiname_init (&pool->multinames[i],
+	      nameid == 0 ? SWFDEC_ABC_MULTINAME_ANY : pool->strings[nameid],
+	      NULL, pool->nssets[nsid]);
+	  break;
+	case 0x1C:
+	  SWFDEC_FIXME ("implement attributes");
+	case 0x1B:
+	  READ_U30 (nsid, bits);
+	  if (nsid >= pool->n_nssets)
+	    THROW (pool, "Cpool index %u is out of range %u.", nsid, pool->n_nssets);
+	  swfdec_abc_multiname_init (&pool->multinames[i],
+	      NULL, NULL, pool->nssets[nsid]);
+	  break;
+	default:
+	  THROW (pool, "Cpool entry %u is wrong type.", i);
+      }
+      SWFDEC_LOG ("  multiname %u: %s::%s", i, pool->multinames[i].ns == NULL ? 
+	  (pool->multinames[i].nsset ? "[SET]" : "[RUNTIME]") : 
+	  pool->multinames[i].ns == SWFDEC_ABC_MULTINAME_ANY ? "[*]" : pool->multinames[i].ns->uri,
+	  pool->multinames[i].name == NULL ? "[RUNTIME]" : 
+	  pool->multinames[i].name == SWFDEC_ABC_MULTINAME_ANY ? "[*]" : pool->multinames[i].name);
+    }
+  }
+
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_method (SwfdecAbcPool *pool, SwfdecBits *bits, SwfdecAbcTraits *traits, SwfdecAbcFunction **ret)
+{
+  guint id;
+
+  READ_U30 (id, bits);
+  if (id >= pool->n_functions) {
+    THROW (pool, "Method_info %u exceeds method_count=%u.", id, pool->n_functions);
+  } else if (pool->functions[id] == NULL) {
+    THROW (pool, "MethodInfo-%u referenced before definition.", id);
+  } else if (traits) {
+    if (!swfdec_abc_function_bind (pool->functions[id], traits)) {
+      THROW (pool, "Function %s has already been bound to %s.", pool->functions[id]->name,
+	  pool->functions[id]->bound_traits->name);
+    }
+    g_assert (traits->construct == NULL);
+    traits->construct = pool->functions[id];
+    SWFDEC_LOG ("binding method %u to traits %s", id, traits->name);
+  } else {
+    SWFDEC_LOG ("found method %u", id);
+  }
+  if (ret)
+    *ret = pool->functions[id];
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_traits (SwfdecAbcPool *pool, SwfdecAbcTraits *traits, SwfdecBits *bits)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  SwfdecAbcTraits *base = traits->base;
+  guint i, n_slots, n_methods, n_traits;
+  gboolean early, metadata;
+
+  READ_U30 (n_traits, bits);
+  SWFDEC_LOG ("%u traits", n_traits);
+
+  /* ensure we can copy protected traits from base class into new protected namespace */
+  traits->n_traits = n_traits;
+  if (base && base->protected_ns && traits->protected_ns) {
+    for (i = 0; i < base->n_traits; i++) {
+      if (base->traits[i].ns == base->protected_ns)
+	traits->n_traits++;
+    }
+  }
+
+  if (traits->n_traits) {
+    traits->traits = swfdec_as_context_try_new (context, SwfdecAbcTrait, traits->n_traits);
+    if (traits->traits == NULL) {
+      traits->n_traits = 0;
+      return FALSE;
+    }
+  }
+  if (base && base->protected_ns && traits->protected_ns) {
+    traits->n_traits = n_traits;
+    for (i = 0; i < base->n_traits; i++) {
+      if (base->traits[i].ns == base->protected_ns) {
+	traits->traits[traits->n_traits] = base->traits[i];
+	traits->traits[traits->n_traits].ns = traits->protected_ns;
+	traits->n_traits++;
+      }
+    }
+  }
+
+
+  if (base) {
+    n_slots = base->n_slots;
+    n_methods = base->n_methods;
+  } else {
+    n_slots = 0;
+    n_methods = 0;
+  }
+
+  early = base ? swfdec_abc_traits_allow_early_binding (traits) : TRUE;
+  SWFDEC_LOG ("  %sallowing early binding", early ? "" : "NOT ");
+
+  for (i = 0; i < n_traits; i++) {
+    SwfdecAbcTrait *trait = &traits->traits[i];
+    guint type;
+    SWFDEC_LOG ("trait %u", i);
+    if (!swfdec_abc_pool_parse_qname (pool, bits, &trait->ns, &trait->name))
+      return FALSE;
+    SWFDEC_LOG ("  name: %s::%s", trait->ns->uri, trait->name);
+
+    /* reserved = */ swfdec_bits_getbit (bits);
+    metadata = swfdec_bits_getbit (bits);
+    SWFDEC_LOG ("  metadata: %d", metadata);
+    trait->override = swfdec_bits_getbit (bits);
+    SWFDEC_LOG ("  override: %d", trait->override);
+    trait->final = swfdec_bits_getbit (bits);
+    SWFDEC_LOG ("  final: %d", trait->final);
+    type = swfdec_bits_getbits (bits, 4);
+    SWFDEC_LOG ("  type: %u", type);
+    switch (type) {
+      case 0: /* slot */
+      case 6: /* const */
+      case 4: /* class */
+	{
+          guint slot;
+	  READ_U30 (slot, bits);
+	  if (!early)
+	    slot = 0;
+	  if (slot == 0) {
+	    slot = n_slots;
+	    n_slots++;
+	    SWFDEC_LOG ("  slot: %u (automatic)", slot);
+	  } else {
+	    if (slot > n_traits || slot == 0)
+	      THROW (pool, "The ABC data is corrupt, attempt to read out of bounds.");
+	    if (slot > n_slots)
+	      n_slots = slot;
+	    slot--;
+	    if (base && slot < base->n_slots)
+	      THROW (pool, "Illegal override of %s in %s.", trait->name, traits->name);
+	    SWFDEC_LOG ("  slot: %u", slot);
+	  }
+
+	  if (swfdec_abc_traits_get_trait (traits, trait->ns, trait->name))
+	    THROW (pool, "The ABC data is corrupt, attempt to read out of bounds.");
+				
+	  if (type == 4) {
+	    guint id;
+	    READ_U30 (id, bits);
+	    if (id >= pool->n_classes)
+	      THROW (pool, "ClassInfo %u exceeds class_count=%u.", id, pool->n_functions);
+	    if (pool->classes[id] == NULL)
+	      THROW (pool, "ClassInfo-%u is referenced before definition.", id);
+
+	    trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_CONST, slot);
+	    trait->default_index = id;
+	    trait->default_type = G_MAXUINT; /* magic value */
+	  } else {
+	    g_assert (type == 0 || type == 6);
+	    READ_U30 (trait->traits_type, bits);
+	    READ_U30 (trait->default_index, bits);
+	    if (trait->default_index) {
+	      trait->default_type = swfdec_bits_get_u8 (bits);
+	    }
+	    trait->type = SWFDEC_ABC_BINDING_NEW (type == 0 ? SWFDEC_ABC_TRAIT_SLOT : SWFDEC_ABC_TRAIT_CONST, slot);
+	  }
+	}
+	break;
+      case 1: /* method */
+      case 2: /* getter */
+      case 3: /* setter */
+	{
+	  guint ignore, method_id;
+	  SwfdecAbcBinding bind;
+	  const SwfdecAbcTrait *found;
+	  SwfdecAbcFunction *fun;
+	  READ_U30 (ignore, bits);
+	  SWFDEC_LOG ("  display id = %u (ignored)", ignore);
+	  READ_U30 (method_id, bits);
+	  if (method_id >= pool->n_functions) {
+	    THROW (pool, "Method_info %u exceeds method_count=%u.", method_id, pool->n_functions);
+	  } else if (pool->functions[method_id] == NULL) {
+	    THROW (pool, "MethodInfo-%u referenced before definition.", method_id);
+	  } else {
+	    fun = pool->functions[method_id];
+	  }
+	  if (!swfdec_abc_function_bind (fun, traits)) {
+	    THROW (pool, "Function %s has already been bound to %s.", traits->name,
+		fun->bound_traits->name);
+	  }
+
+	  if (traits->base && (found = swfdec_abc_traits_find_trait (traits->base,
+	      trait->ns == traits->protected_ns ? traits->base->protected_ns: trait->ns, 
+	      trait->name))) {
+	    bind = found->type;
+	    SWFDEC_LOG ("  found method %u of type %u to override", 
+		SWFDEC_ABC_BINDING_GET_ID (bind), SWFDEC_ABC_BINDING_GET_TYPE (bind));
+	    trait->default_index = found->default_index;
+	    trait->default_type = found->default_type;
+	  } else {
+	    bind = SWFDEC_ABC_BINDING_NONE;
+	  }
+
+	  if (type == 1) { 
+	    /* method */
+	    if (bind == SWFDEC_ABC_BINDING_NONE) {
+	      if (trait->override)
+		THROW (pool, "Illegal override of %s in %s.", trait->name, traits->name);
+	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_METHOD, n_methods);
+	      SWFDEC_LOG ("  method: %u (new)", n_methods);
+	      n_methods++;
+	    } else if (SWFDEC_ABC_BINDING_IS_TYPE (bind, SWFDEC_ABC_TRAIT_METHOD)) {
+	      if (!trait->override)
+		THROW (pool, "Illegal override of %s in %s.", trait->name, traits->name);
+	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_METHOD, 
+		  SWFDEC_ABC_BINDING_GET_ID (bind));
+	      SWFDEC_LOG ("  method: %u (override)", SWFDEC_ABC_BINDING_GET_ID (bind));
+	    } else {
+	      THROW (pool, "The ABC data is corrupt, attempt to read out of bounds.");
+	    }
+	    trait->default_index = method_id;
+	  } else {
+	    SwfdecAbcTraitType ttype = type == 2 ? SWFDEC_ABC_TRAIT_GET : SWFDEC_ABC_TRAIT_SET;
+	    /* getter or setter */
+
+	    /* check override */
+	    if (bind == SWFDEC_ABC_BINDING_NONE) {
+	      if (trait->override)
+		THROW (pool, "Illegal override of %s in %s.", trait->name, traits->name);
+	    } else if (SWFDEC_ABC_BINDING_IS_ACCESSOR (bind)) {
+	      if ((trait->override ? TRUE : FALSE) != ((SWFDEC_ABC_BINDING_GET_TYPE (bind) & ttype) == ttype))
+		THROW (pool, "Illegal override of %s in %s.", trait->name, traits->name);
+	      SWFDEC_LOG ("  method: %u (override)", SWFDEC_ABC_BINDING_GET_ID (bind));
+	    } else {
+	      THROW (pool, "The ABC data is corrupt, attempt to read out of bounds.");
+	    }
+
+	    /* try to find own trait */
+	    found = swfdec_abc_traits_get_trait (traits, trait->ns, trait->name);
+	    if (found) {
+	      /* FIXME: This is kinda (read: very) hacky */
+	      trait = (SwfdecAbcTrait *) found;
+	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_TRAIT_GETSET, 
+		  SWFDEC_ABC_BINDING_GET_ID (trait->type));
+	      SWFDEC_LOG ("  method: %u (reuse)", SWFDEC_ABC_BINDING_GET_ID (trait->type));
+	    } else if (bind == SWFDEC_ABC_BINDING_NONE) {
+	      trait->type = SWFDEC_ABC_BINDING_NEW (ttype, n_methods);
+	      SWFDEC_LOG ("  method: %u (new)", n_methods);
+	      n_methods += 2;
+	    } else {
+	      trait->type = SWFDEC_ABC_BINDING_NEW (SWFDEC_ABC_BINDING_GET_TYPE (bind) | ttype,
+		  SWFDEC_ABC_BINDING_GET_ID (bind));
+	    }
+	    if (type == 2) {
+	      trait->default_index = method_id;
+	    } else {
+	      trait->default_type = method_id;
+	    }
+	  }
+	}
+        break;
+      default:
+	THROW (pool, "Unsupported traits kind=%u.", type);
+    }
+
+    if (metadata) {
+      guint ignore, j, count;
+      READ_U30 (count, bits);
+  
+      SWFDEC_INFO ("parse metadata, in particular \"NeedsDxns\"");
+      for (j = 0; j < count; j++) {
+	READ_U30 (ignore, bits);
+      }
+    }
+  }
+
+  traits->n_slots = n_slots;
+  traits->n_methods = n_methods;
+
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_methods (SwfdecAbcPool *pool, SwfdecBits *bits,
+    const GCallback *natives, guint n_natives)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  guint i;
+
+  READ_U30 (pool->n_functions, bits);
+  SWFDEC_LOG ("%u methods", pool->n_functions);
+  if (pool->n_functions) {
+    gboolean param_names, optional, native;
+    pool->functions = swfdec_as_context_try_new (context, SwfdecAbcFunction *, pool->n_functions);
+    if (pool->functions == NULL) {
+      pool->n_functions = 0;
+      return FALSE;
+    }
+    for (i = 0; i < pool->n_functions; i++) {
+      guint id, j, len;
+      SwfdecAbcFunction *fun = pool->functions[i] = 
+	g_object_new (SWFDEC_TYPE_ABC_FUNCTION, "context", context, NULL);
+      fun->pool = pool;
+      READ_U30 (len, bits);
+      SWFDEC_LOG ("  function %u:", i);
+      fun->args = swfdec_as_context_try_new (context, SwfdecAbcFunctionArgument, len + 1);
+      if (fun->args == NULL)
+	return FALSE;
+      fun->n_args = len;
+      fun->min_args = len;
+      READ_U30 (id, bits);
+      if (id == 0) {
+	fun->return_type = NULL;
+      } else if (id < pool->n_multinames) {
+	fun->return_type = &pool->multinames[id];
+      } else {
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_multinames);
+      }
+      SWFDEC_LOG ("    return type: %s", fun->return_type ? ((SwfdecAbcMultiname *) fun->return_type)->name : "void");
+      for (j = 1; j <= fun->n_args; j++) {
+	READ_U30 (id, bits);
+	if (id == 0) {
+	  fun->args[j].type = NULL;
+	} else if (id < pool->n_multinames) {
+	  fun->args[j].type = &pool->multinames[id];
+	} else {
+	  THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_multinames);
+	}
+	SWFDEC_LOG ("    argument %u: type %s", j, fun->args[j].type ? ((SwfdecAbcMultiname *) fun->args[j].type)->name : "void");
+      }
+      READ_U30 (id, bits);
+      if (id > pool->n_strings) {
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_strings);
+      } else if (id > 0) {
+	fun->name = pool->strings[id];
+      }
+      param_names = swfdec_bits_getbit (bits);
+      fun->set_dxns = swfdec_bits_getbit (bits);
+      native = swfdec_bits_getbit (bits);
+      /* ignored = */ swfdec_bits_getbit (bits);
+      optional = swfdec_bits_getbit (bits);
+      fun->need_rest = swfdec_bits_getbit (bits);
+      fun->need_activation = swfdec_bits_getbit (bits);
+      fun->need_arguments = swfdec_bits_getbit (bits);
+      if (native) {
+
+	if (i >= n_natives) {
+	  SWFDEC_ERROR ("only %u native methods specified, but wanting index %u", n_natives, i);
+	} else {
+	  fun->native = natives[i];
+	}
+	if (fun->native == NULL) {
+	  SWFDEC_INFO ("no native for index %u", i);
+	}
+      }
+      if (optional) {
+	READ_U30 (len, bits);
+	if (len == 0 || len > fun->n_args)
+	  return FALSE;
+	fun->min_args -= len;
+	for (j = fun->min_args + 1; j <= fun->n_args; j++) {
+	  READ_U30 (id, bits);
+	  fun->args[j].default_index = id;
+	  fun->args[j].default_type = swfdec_bits_get_u8 (bits);
+	}
+      }
+      if (param_names) {
+	/* Tamarin doesn't parse this, so we must not error out here */
+	for (j = 1; j <= fun->n_args; j++) {
+	  id = swfdec_bits_get_vu32 (bits);
+	  if (id > 0 && id < pool->n_strings)
+	    fun->args[j].name = pool->strings[id];
+	}
+      }
+    }
+  }
+
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_skip_metadata (SwfdecAbcPool *pool, SwfdecBits *bits)
+{
+  guint i, j, ignore, count, count2;
+
+  READ_U30 (count, bits);
+  for (i = 0; i < count; i++) {
+    READ_U30 (ignore, bits);
+    READ_U30 (count2, bits);
+    for (j = 0; j < count2; j++) {
+      READ_U30 (ignore, bits); /* key */
+      READ_U30 (ignore, bits); /* value */
+    }
+  }
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_instance (SwfdecAbcPool *pool, guint instance_id, SwfdecBits *bits)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  gboolean protected_ns;
+  SwfdecAbcTraits *traits;
+  guint id, i, n;
+
+  SWFDEC_LOG ("instance: %u", instance_id);
+  traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
+  traits->pool = pool;
+  if (!swfdec_abc_pool_parse_qname (pool, bits, &traits->ns, &traits->name))
+    return FALSE;
+  SWFDEC_LOG ("  name: %s::%s", traits->ns->uri, traits->name);
+  
+  READ_U30 (id, bits);
+  /* id == 0 means no base traits */
+  if (id >= pool->n_multinames) {
+    THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_multinames);
+  } else if (id > 0) {
+    SwfdecAbcTraits *base = swfdec_abc_global_get_traits_for_multiname (pool->global,
+	&pool->multinames[id]);
+    if (base == NULL)
+      THROW (pool, "Class %s could not be found.", pool->multinames[id].name);
+    if (base->final || 
+	(pool->global->pool != NULL && 
+	 (base == SWFDEC_ABC_CLASS_TRAITS (context) || base == SWFDEC_ABC_FUNCTION_TRAITS (context)))) {
+      THROW (pool, "Class %s cannot extend final base class.", pool->multinames[id].name);
+    }
+    if (base->interface || traits->interface) {
+      THROW (pool, "Class %s cannot extend %s.", pool->multinames[id].name, base->name);
+    }
+    traits->base = base;
+    SWFDEC_LOG ("  base: %s::%s", base->ns->uri, base->name);
+  } else {
+    SWFDEC_LOG ("  no base type");
+  }
+  /* reserved = */ swfdec_bits_getbits (bits, 4);
+  protected_ns = swfdec_bits_getbit (bits);
+  traits->interface = swfdec_bits_getbit (bits);
+  traits->final = swfdec_bits_getbit (bits);
+  traits->sealed = swfdec_bits_getbit (bits);
+  if (protected_ns) {
+    READ_U30 (id, bits);
+    if (id == 0) {
+      /* traits->protected_ns = NULL; */
+    } else if (id < pool->n_namespaces) {
+      traits->protected_ns = pool->namespaces[id];
+    } else if (id != 0) {
+      THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_multinames);
+    }
+  }
+  READ_U30 (n, bits);
+  if (n > 0) {
+    SWFDEC_FIXME ("implement interface parsing");
+    for (i = 0; i < n; i++) {
+      READ_U30 (id, bits);
+    }
+  } 
+  if (!swfdec_abc_pool_parse_method (pool, bits, traits, NULL))
+    return FALSE;
+
+  if (!swfdec_abc_pool_parse_traits (pool, traits, bits))
+    return FALSE;
+  swfdec_abc_global_add_traits (pool->global, traits);
+  pool->instances[instance_id] = traits;
+
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_instances (SwfdecAbcPool *pool, SwfdecBits *bits)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  guint i;
+
+  READ_U30 (pool->n_classes, bits);
+  SWFDEC_LOG ("%u classes", pool->n_classes);
+  if (pool->n_classes) {
+    pool->instances = swfdec_as_context_try_new (context, SwfdecAbcTraits *, pool->n_classes);
+    pool->classes = swfdec_as_context_try_new (context, SwfdecAbcTraits *, pool->n_classes);
+    if (pool->instances == NULL || pool->classes == NULL) {
+      if (pool->instances) {
+	swfdec_as_context_free (context, sizeof (SwfdecAbcFunction *) * pool->n_classes, pool->instances);
+	pool->instances = NULL;
+      }
+      if (pool->classes) {
+	swfdec_as_context_free (context, sizeof (SwfdecAbcFunction *) * pool->n_classes, pool->classes);
+	pool->classes = NULL;
+      }
+      pool->n_classes = 0;
+      return FALSE;
+    }
+    for (i = 0; i < pool->n_classes; i++) {
+      if (!swfdec_abc_pool_parse_instance (pool, i, bits))
+	return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_classes (SwfdecAbcPool *pool, SwfdecBits *bits)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  guint i;
+
+  if (pool->n_classes) {
+    for (i = 0; i < pool->n_classes; i++) {
+      SwfdecAbcTraits *traits;
+
+      SWFDEC_LOG ("class %u", i);
+      traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
+      traits->pool = pool;
+
+      traits->ns = pool->instances[i]->ns;
+      traits->name = swfdec_as_context_give_string (context,
+	  g_strconcat (pool->instances[i]->name, "$", NULL));
+      traits->final = TRUE;
+      traits->sealed = FALSE;
+      if (SWFDEC_ABC_GLOBAL (context->global)->pool)
+	traits->base = SWFDEC_ABC_CLASS_TRAITS (context);
+      else
+	traits->base = pool->instances[SWFDEC_ABC_TYPE_CLASS];
+      g_assert (traits->base);
+
+      if (!swfdec_abc_pool_parse_method (pool, bits, traits, NULL))
+	return FALSE;
+
+      if (!swfdec_abc_pool_parse_traits (pool, traits, bits))
+	return FALSE;
+
+      traits->instance_traits = pool->instances[i];
+      pool->classes[i] = traits;
+    }
+  }
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_scripts (SwfdecAbcPool *pool, SwfdecBits *bits)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  SwfdecAbcScript *script = NULL;
+  SwfdecAbcTraits *traits;
+  SwfdecAbcFunction *fun;
+  guint i, j, n_scripts;
+
+  READ_U30 (n_scripts, bits);
+  SWFDEC_LOG ("%u scripts ", n_scripts);
+  for (i = 0; i < n_scripts; i++) {
+    SWFDEC_LOG ("script %u", i);
+    traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
+    traits->pool = pool;
+    traits->final = TRUE;
+    traits->ns = context->public_ns;
+    traits->name = SWFDEC_AS_STR_global;
+    if (SWFDEC_ABC_GLOBAL (context->global)->pool)
+      traits->base = SWFDEC_ABC_OBJECT_TRAITS (context);
+    else
+      traits->base = pool->instances[SWFDEC_ABC_TYPE_OBJECT];
+    if (!swfdec_abc_pool_parse_method (pool, bits, traits, &fun))
+      return FALSE;
+    traits->construct = fun;
+    if (!swfdec_abc_pool_parse_traits (pool, traits, bits))
+      return FALSE;
+    script = g_object_new (SWFDEC_TYPE_ABC_SCRIPT, "context", context, NULL);
+    script->traits = traits;
+    for (j = 0; j < traits->n_traits; j++) {
+      SwfdecAbcTrait *trait = &traits->traits[j];
+      if (trait->type == SWFDEC_ABC_TRAIT_NONE)
+	continue;
+      swfdec_abc_global_add_script (pool->global, trait->ns, trait->name, script, 
+	  i + 1 == n_scripts);
+    }
+  }
+  if (script == 0)
+    THROW (pool, "No entry point was found.");
+  pool->main = script;
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse_bodies (SwfdecAbcPool *pool, SwfdecBits *bits)
+{
+  SwfdecAsContext *context = swfdec_gc_object_get_context (pool);
+  SwfdecAbcTraits *traits;
+  SwfdecAbcFunction *fun;
+  guint i, j, max_scope, min_scope, n_bodies, size;
+
+  READ_U30 (n_bodies, bits);
+  SWFDEC_LOG ("%u bodies", n_bodies);
+  for (i = 0; i < n_bodies; i++) {
+    SWFDEC_LOG ("body %u", i);
+    if (!swfdec_abc_pool_parse_method (pool, bits, NULL, &fun))
+      return FALSE;
+    if (swfdec_abc_function_is_native (fun))
+      THROW (pool, "Native method %"G_GSIZE_FORMAT" has illegal method body.", fun - pool->functions[0]);
+    if (fun->bound_traits && fun->bound_traits->interface)
+      THROW (pool, "Interface method %"G_GSIZE_FORMAT" has illegal method body.", fun - pool->functions[0]);
+    if (fun->code != NULL)
+      THROW (pool, "Method %"G_GSIZE_FORMAT" has a duplicate method body.", fun - pool->functions[0]);
+
+    READ_U30 (fun->n_stack, bits);
+    SWFDEC_LOG ("  stack: %u", fun->n_stack);
+    READ_U30 (fun->n_locals, bits);
+    if (fun->n_args >= fun->n_locals)
+      THROW (pool, "The ABC data is corrupt, attempt to read out of bounds.");
+    SWFDEC_LOG ("  locals: %u", fun->n_locals);
+    READ_U30 (min_scope, bits);
+    READ_U30 (max_scope, bits);
+    if (min_scope > max_scope)
+      THROW (pool, "The ABC data is corrupt, attempt to read out of bounds.");
+    fun->n_scope = max_scope - min_scope;
+    SWFDEC_LOG ("  scope: %u (%u - %u)", fun->n_scope, min_scope, max_scope);
+    READ_U30 (size, bits);
+    if (size == 0)
+      THROW (pool, "Invalid code_length=0.");
+    SWFDEC_LOG ("  code: %u bytes", size);
+    fun->code = swfdec_bits_get_buffer (bits, size);
+    if (fun->code == NULL)
+      THROW (pool, "The ABC data is corrupt, attempt to read out of bounds.");
+
+    READ_U30 (fun->n_exceptions, bits);
+    SWFDEC_LOG ("  exceptions: %u", fun->n_exceptions);
+    if (fun->n_exceptions) {
+      fun->exceptions = swfdec_as_context_try_new (context, SwfdecAbcException, fun->n_exceptions);
+      if (fun->exceptions == NULL) {
+	fun->n_exceptions = 0;
+	return FALSE;
+      }
+      for (j = 0; j < fun->n_exceptions; j++) {
+	SwfdecAbcException *ex = &fun->exceptions[j];
+	READ_U30 (ex->from, bits);
+	READ_U30 (ex->to, bits);
+	READ_U30 (ex->target, bits);
+	READ_U30 (ex->type, bits);
+	READ_U30 (ex->var, bits);
+      }
+    }
+
+    traits = g_object_new (SWFDEC_TYPE_ABC_TRAITS, "context", context, NULL);
+    traits->pool = pool;
+    traits->final = TRUE;
+    traits->ns = context->public_ns;
+    traits->name = SWFDEC_AS_STR_EMPTY;
+    if (SWFDEC_ABC_GLOBAL (context->global)->pool)
+      traits->base = SWFDEC_ABC_OBJECT_TRAITS (context);
+    else
+      traits->base = pool->instances[SWFDEC_ABC_TYPE_OBJECT];
+    if (!swfdec_abc_pool_parse_traits (pool, traits, bits))
+      return FALSE;
+    fun->activation = traits;
+  }
+  return TRUE;
+}
+
+static gboolean
+swfdec_abc_pool_parse (SwfdecAbcPool *pool, SwfdecBits *bits,
+    const GCallback *natives, guint n_natives)
+{
+  return swfdec_abc_pool_parse_constants (pool, bits) &&
+      swfdec_abc_pool_parse_methods (pool, bits, natives, n_natives) &&
+      swfdec_abc_pool_skip_metadata (pool, bits) &&
+      swfdec_abc_pool_parse_instances (pool, bits) &&
+      swfdec_abc_pool_parse_classes (pool, bits) &&
+      swfdec_abc_pool_parse_scripts (pool, bits) &&
+      swfdec_abc_pool_parse_bodies (pool, bits);
+}
+
+SwfdecAbcPool *
+swfdec_abc_pool_new (SwfdecAsContext *context, SwfdecBits *bits)
+{
+  return swfdec_abc_pool_new_trusted (context, bits, NULL, 0);
+}
+
+SwfdecAbcPool *
+swfdec_abc_pool_new_trusted (SwfdecAsContext *context, SwfdecBits *bits,
+    const GCallback *natives, guint n_natives)
+{
+  SwfdecAbcPool *pool;
+  guint major, minor;
+
+  g_return_val_if_fail (SWFDEC_IS_AS_CONTEXT (context), NULL);
+  g_return_val_if_fail (SWFDEC_IS_ABC_GLOBAL (context->global), NULL);
+  g_return_val_if_fail (bits != NULL, NULL);
+
+  pool = g_object_new (SWFDEC_TYPE_ABC_POOL, "context", context, NULL);
+  pool->global = SWFDEC_ABC_GLOBAL (context->global);
+
+  minor = swfdec_bits_get_u16 (bits);
+  major = swfdec_bits_get_u16 (bits);
+  SWFDEC_LOG ("  major version: %u", major);
+  SWFDEC_LOG ("  minor version: %u", minor);
+  if (major == 46 && minor == 16) {
+    if (!swfdec_abc_pool_parse (pool, bits, natives, n_natives)) {
+      swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_VERIFY_ERROR,
+	  "The ABC data is corrupt, attempt to read out of bounds.");
+      return NULL;
+    }
+  } else {
+    swfdec_as_context_throw_abc (context, SWFDEC_ABC_TYPE_VERIFY_ERROR,
+	"Not an ABC pool.  major_version=%u minor_version=%u.", major, minor);
+    return NULL;
+  }
+  
+//#define SWFDEC_PRINT_STUBS
+#ifdef SWFDEC_PRINT_STUBS
+  {
+    guint i;
+
+    if (SWFDEC_ABC_GLOBAL (context->global)->pool == NULL)
+      SWFDEC_ABC_GLOBAL (context->global)->pool = pool;
+    
+    /* update machine types */
+    SWFDEC_ABC_BOOLEAN_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
+    SWFDEC_ABC_INT_TRAITS (context)->machine_type = SWFDEC_ABC_INT;
+    SWFDEC_ABC_UINT_TRAITS (context)->machine_type = SWFDEC_ABC_UINT;
+    SWFDEC_ABC_NUMBER_TRAITS (context)->machine_type = SWFDEC_ABC_DOUBLE;
+    SWFDEC_ABC_STRING_TRAITS (context)->machine_type = SWFDEC_ABC_STRING;
+
+    g_print ("missing implementations:\n");
+    for (i = 0; i < pool->n_functions; i++) {
+      SwfdecAbcFunction *fun = pool->functions[i];
+      char *name;
+      if (fun->code != NULL)
+	continue;
+      /* This is why we can't print this stuff by default: We need to resolve
+       * the function, which could throw */
+      if (!swfdec_abc_function_resolve (fun) ||
+	  (fun->bound_traits != NULL && !swfdec_abc_traits_resolve (fun->bound_traits))) {
+	g_assert_not_reached ();
+      }
+      name = swfdec_abc_function_describe (fun);
+      g_print ("%s %s\n", fun->native == NULL ? "XXX" : "   ", name);
+      g_free (name);
+      }
+  }
+#endif
+
+  return pool;
+}
+
+gboolean
+swfdec_abc_pool_get_constant (SwfdecAbcPool *pool, SwfdecAsValue *value, 
+    guint type, guint id)
+{
+  g_return_val_if_fail (SWFDEC_IS_ABC_POOL (pool), FALSE);
+  g_return_val_if_fail (value != NULL, FALSE);
+
+  switch (type) {
+    case SWFDEC_ABC_CONST_UNDEFINED:
+      SWFDEC_AS_VALUE_SET_UNDEFINED (value);
+      break;
+    case SWFDEC_ABC_CONST_STRING:
+      if (id >= pool->n_strings)
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_strings);
+      SWFDEC_AS_VALUE_SET_STRING (value, pool->strings[id]);
+      break;
+    case SWFDEC_ABC_CONST_INT:
+      if (id >= pool->n_ints)
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_ints);
+      SWFDEC_AS_VALUE_SET_INT (value, pool->ints[id]);
+      break;
+    case SWFDEC_ABC_CONST_UINT:
+      if (id >= pool->n_uints)
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_uints);
+      SWFDEC_AS_VALUE_SET_NUMBER (value, pool->uints[id]);
+      break;
+    case SWFDEC_ABC_CONST_DOUBLE:
+      if (id >= pool->n_doubles)
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_doubles);
+      SWFDEC_AS_VALUE_SET_NUMBER (value, pool->doubles[id]);
+      break;
+    case SWFDEC_ABC_CONST_FALSE:
+      SWFDEC_AS_VALUE_SET_BOOLEAN (value, FALSE);
+      break;
+    case SWFDEC_ABC_CONST_TRUE:
+      SWFDEC_AS_VALUE_SET_BOOLEAN (value, TRUE);
+      break;
+    case SWFDEC_ABC_CONST_NULL:
+      SWFDEC_AS_VALUE_SET_NULL (value);
+      break;
+    case SWFDEC_ABC_CONST_PRIVATE_NAMESPACE:
+    case SWFDEC_ABC_CONST_NAMESPACE:
+    case SWFDEC_ABC_CONST_PACKAGE_NAMESPACE:
+    case SWFDEC_ABC_CONST_INTERNAL_NAMESPACE:
+    case SWFDEC_ABC_CONST_PROTECTED_NAMESPACE:
+    case SWFDEC_ABC_CONST_EXPLICIT_NAMESPACE:
+    case SWFDEC_ABC_CONST_STATIC_PROTECTED_NAMESPACE:
+      if (id >= pool->n_namespaces)
+	THROW (pool, "Cpool index %u is out of range %u.", id, pool->n_namespaces);
+      SWFDEC_AS_VALUE_SET_NAMESPACE (value, pool->namespaces[id]);
+      break;
+    default:
+      THROW (pool, "Illegal default value for type %s.", "FIXME");
+  }
+  return TRUE;
+}
diff --git a/swfdec/swfdec_abc_pool.h b/swfdec/swfdec_abc_pool.h
new file mode 100644
index 0000000..313bfc4
--- /dev/null
+++ b/swfdec/swfdec_abc_pool.h
@@ -0,0 +1,108 @@
+/* Swfdec
+ * Copyright (C) 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
+ * 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_ABC_POOL_H_
+#define _SWFDEC_ABC_POOL_H_
+
+#include <swfdec/swfdec_abc_global.h>
+#include <swfdec/swfdec_abc_multiname.h>
+#include <swfdec/swfdec_abc_namespace.h>
+#include <swfdec/swfdec_abc_ns_set.h>
+#include <swfdec/swfdec_abc_types.h>
+#include <swfdec/swfdec_bits.h>
+#include <swfdec/swfdec_gc_object.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+  SWFDEC_ABC_CONST_UNDEFINED = 0,
+  SWFDEC_ABC_CONST_STRING = 1,
+  SWFDEC_ABC_CONST_INT = 3,
+  SWFDEC_ABC_CONST_UINT = 4,
+  SWFDEC_ABC_CONST_PRIVATE_NAMESPACE = 5,
+  SWFDEC_ABC_CONST_DOUBLE = 6,
+  SWFDEC_ABC_CONST_NAMESPACE = 8,
+  SWFDEC_ABC_CONST_FALSE = 10,
+  SWFDEC_ABC_CONST_TRUE = 11,
+  SWFDEC_ABC_CONST_NULL = 12,
+  SWFDEC_ABC_CONST_PACKAGE_NAMESPACE = 22,
+  SWFDEC_ABC_CONST_INTERNAL_NAMESPACE = 23,
+  SWFDEC_ABC_CONST_PROTECTED_NAMESPACE = 24,
+  SWFDEC_ABC_CONST_EXPLICIT_NAMESPACE = 25,
+  SWFDEC_ABC_CONST_STATIC_PROTECTED_NAMESPACE = 26
+} SwfdecAbcConstant;
+
+//typedef struct _SwfdecAbcPool SwfdecAbcPool;
+typedef struct _SwfdecAbcPoolClass SwfdecAbcPoolClass;
+
+#define SWFDEC_TYPE_ABC_POOL                    (swfdec_abc_pool_get_type())
+#define SWFDEC_IS_ABC_POOL(obj)                 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_ABC_POOL))
+#define SWFDEC_IS_ABC_POOL_CLASS(klass)         (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_ABC_POOL))
+#define SWFDEC_ABC_POOL(obj)                    (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_ABC_POOL, SwfdecAbcPool))
+#define SWFDEC_ABC_POOL_CLASS(klass)            (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_ABC_POOL, SwfdecAbcPoolClass))
+#define SWFDEC_ABC_POOL_GET_CLASS(obj)          (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_ABC_POOL, SwfdecAbcPoolClass))
+
+struct _SwfdecAbcPool {
+  SwfdecGcObject	object;
+
+  SwfdecAbcGlobal *	global;		/* the global object we belong to */
+
+  int *			ints;		/* all integer values in the pool */
+  guint			n_ints;		/* number of integers */
+  guint *		uints;		/* all unsigned integer values in the pool */
+  guint			n_uints;	/* number of unsigned integers */
+  double *		doubles;	/* all double values in the pool */
+  guint			n_doubles;	/* number of doubles */
+  const char **		strings;	/* all string values in the pool */
+  guint			n_strings;	/* number of strings */
+  SwfdecAbcNamespace **	namespaces;	/* all the namespaces in use */
+  guint			n_namespaces;	/* number of namespaces */
+  SwfdecAbcNsSet **	nssets;		/* all the namespace sets in use */
+  guint			n_nssets;	/* number of namespace sets */
+  SwfdecAbcMultiname *	multinames;   	/* all the multinames in use */
+  guint			n_multinames;	/* number of multinames */
+  SwfdecAbcFunction **	functions;   	/* all the functions defined */
+  guint			n_functions;	/* number of functions */
+  SwfdecAbcTraits **	instances;   	/* instance infos for the defined classes */
+  SwfdecAbcTraits **	classes;   	/* all the classes defined */
+  guint			n_classes;   	/* number of classes */
+  SwfdecAbcScript *	main;		/* main script */
+};
+
+struct _SwfdecAbcPoolClass {
+  SwfdecGcObjectClass	object_class;
+};
+
+GType		swfdec_abc_pool_get_type	(void);
+
+SwfdecAbcPool *	swfdec_abc_pool_new		(SwfdecAsContext *	context,
+						 SwfdecBits *		bits);
+SwfdecAbcPool *	swfdec_abc_pool_new_trusted	(SwfdecAsContext *	context,
+						 SwfdecBits *		bits,
+						 const GCallback *	natives,
+						 guint			n_natives);
+
+gboolean	swfdec_abc_pool_get_constant	(SwfdecAbcPool *	pool,
+						 SwfdecAsValue *	value,
+						 guint			type,
+						 guint			id);
+
+
+G_END_DECLS
+#endif
diff --git a/swfdec/swfdec_abc_traits.c b/swfdec/swfdec_abc_traits.c
index b154f2a..5585108 100644
--- a/swfdec/swfdec_abc_traits.c
+++ b/swfdec/swfdec_abc_traits.c
@@ -25,7 +25,7 @@
 
 #include <string.h>
 
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_function.h"
 #include "swfdec_abc_global.h"
 #include "swfdec_abc_internal.h"
@@ -124,7 +124,7 @@ swfdec_abc_traits_resolve (SwfdecAbcTraits *traits)
 {
   SwfdecAsContext *context;
   SwfdecAbcTraits *base;
-  SwfdecAbcFile *pool;
+  SwfdecAbcPool *pool;
   guint i;
 
   g_return_val_if_fail (SWFDEC_IS_ABC_TRAITS (traits), FALSE);
@@ -188,7 +188,7 @@ swfdec_abc_traits_resolve (SwfdecAbcTraits *traits)
 	} else if (trait->default_index == 0) {
 	  SWFDEC_AS_VALUE_SET_UNDEFINED (&traits->slots[slot]);
 	} else {
-	  if (!swfdec_abc_file_get_constant (pool, &traits->slots[slot],
+	  if (!swfdec_abc_pool_get_constant (pool, &traits->slots[slot],
 		trait->default_type, trait->default_index))
 	    goto fail;
 	}
diff --git a/swfdec/swfdec_abc_traits.h b/swfdec/swfdec_abc_traits.h
index f8af61d..a1a09a1 100644
--- a/swfdec/swfdec_abc_traits.h
+++ b/swfdec/swfdec_abc_traits.h
@@ -93,7 +93,7 @@ extern const SwfdecAbcTrait swfdec_abc_trait_ambiguous;
 struct _SwfdecAbcTraits {
   SwfdecGcObject		object;
 
-  SwfdecAbcFile *		pool;		/* pool that defined this traits */
+  SwfdecAbcPool *		pool;		/* pool that defined this traits */
   SwfdecAbcNamespace *		ns;		/* namespace of type we represent */
   const char *			name;		/* name of type we represent */
   SwfdecAbcTraits *		base;		/* parent type traits */
diff --git a/swfdec/swfdec_abc_types.h b/swfdec/swfdec_abc_types.h
index d0834e2..c8c5593 100644
--- a/swfdec/swfdec_abc_types.h
+++ b/swfdec/swfdec_abc_types.h
@@ -58,7 +58,7 @@ enum {
 #define SWFDEC_ABC_N_TYPES 29
 
 typedef struct _SwfdecAbcClass SwfdecAbcClass;
-typedef struct _SwfdecAbcFile SwfdecAbcFile;
+typedef struct _SwfdecAbcPool SwfdecAbcPool;
 typedef struct _SwfdecAbcFunction SwfdecAbcFunction;
 typedef struct _SwfdecAbcMultiname SwfdecAbcMultiname;
 typedef struct _SwfdecAbcObject SwfdecAbcObject;
diff --git a/swfdec/swfdec_as_context.c b/swfdec/swfdec_as_context.c
index 246b91b..8b3f6de 100644
--- a/swfdec/swfdec_as_context.c
+++ b/swfdec/swfdec_as_context.c
@@ -27,7 +27,7 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_global.h"
 #include "swfdec_abc_internal.h"
 #include "swfdec_as_array.h"
diff --git a/swfdec/swfdec_sandbox_abc.c b/swfdec/swfdec_sandbox_abc.c
index 0d20ea1..1a181f6 100644
--- a/swfdec/swfdec_sandbox_abc.c
+++ b/swfdec/swfdec_sandbox_abc.c
@@ -23,7 +23,7 @@
 
 #include "swfdec_sandbox_abc.h"
 
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_native.h"
 #include "swfdec_bits.h"
 #include "swfdec_debug.h"
@@ -62,7 +62,7 @@ swfdec_sandbox_abc_constructor (GType type, guint n_construct_properties,
   player = SWFDEC_PLAYER (context);
 
   swfdec_bits_init_data (&bits, swfdec_initialize_abc, sizeof (swfdec_initialize_abc));
-  swfdec_abc_file_new_trusted (context, &bits, swfdec_abc_natives_flash,
+  swfdec_abc_pool_new_trusted (context, &bits, swfdec_abc_natives_flash,
       G_N_ELEMENTS (swfdec_abc_natives_flash));
 
   return object;
diff --git a/swfdec/swfdec_sandbox_as.c b/swfdec/swfdec_sandbox_as.c
index e9223da..9db8087 100644
--- a/swfdec/swfdec_sandbox_as.c
+++ b/swfdec/swfdec_sandbox_as.c
@@ -22,7 +22,7 @@
 #endif
 
 #include "swfdec_sandbox_as.h"
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_native.h"
 #include "swfdec_as_internal.h"
 #include "swfdec_debug.h"
diff --git a/swfdec/swfdec_sprite_movie.c b/swfdec/swfdec_sprite_movie.c
index 90cfb45..7a2b5b8 100644
--- a/swfdec/swfdec_sprite_movie.c
+++ b/swfdec/swfdec_sprite_movie.c
@@ -25,7 +25,7 @@
 
 #include "swfdec_sprite_movie.h"
 #include "swfdec_abc_class.h"
-#include "swfdec_abc_file.h"
+#include "swfdec_abc_pool.h"
 #include "swfdec_abc_global.h"
 #include "swfdec_abc_internal.h"
 #include "swfdec_abc_multiname.h"
@@ -501,7 +501,7 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
     case SWFDEC_TAG_DOABC:
       {
 	SwfdecSandbox *sandbox;
-	SwfdecAbcFile *file;
+	SwfdecAbcPool *file;
 	guint flags;
 	char *name;
 	sandbox = mov->resource->sandbox;
@@ -521,7 +521,7 @@ swfdec_sprite_movie_perform_one_action (SwfdecSpriteMovie *movie, guint tag, Swf
 	SWFDEC_LOG ("  name: %s", name);
 	g_free (name);
 	swfdec_sandbox_use (sandbox);
-	file = swfdec_abc_file_new (SWFDEC_AS_CONTEXT (player), &bits);
+	file = swfdec_abc_pool_new (SWFDEC_AS_CONTEXT (player), &bits);
 	swfdec_sandbox_unuse (sandbox);
       }
       return TRUE;


More information about the Swfdec-commits mailing list