[svn:parrot] r43706 - in trunk: . compilers/data_json compilers/imcc compilers/json compilers/nqp compilers/pct compilers/pge compilers/tge config/auto/sizes docs/book/draft docs/book/pct docs/dev docs/pdds examples/embed examples/languages/abc examples/languages/squaak examples/pge ext/nqp-rx include/parrot lib/Parrot lib/Parrot/Configure/Step ports/cpan ports/cygwin ports/debian ports/fedora ports/mandriva ports/suse runtime/parrot/languages runtime/parrot/library runtime/parrot/library/Math runtime/parrot/library/Math/Random src src/call src/gc src/interp src/pmc src/runcore t/compilers/tge t/library t/native_pbc t/oo t/pmc t/src t/steps/init/hints tools/build tools/dev tools/util

darbelo at svn.parrot.org darbelo at svn.parrot.org
Tue Feb 2 19:38:37 UTC 2010


Author: darbelo
Date: Tue Feb  2 19:38:35 2010
New Revision: 43706
URL: https://trac.parrot.org/parrot/changeset/43706

Log:
Merge pmc_freeze_with_pmcs into trunk.

Added:
   trunk/src/pmc/imageio.pmc
      - copied unchanged from r43704, branches/pmc_freeze_with_pmcs/src/pmc/imageio.pmc
Modified:
   trunk/   (props changed)
   trunk/MANIFEST
   trunk/PBC_COMPAT
   trunk/compilers/data_json/Rules.mak   (props changed)
   trunk/compilers/imcc/Rules.mak   (props changed)
   trunk/compilers/json/Rules.mak   (props changed)
   trunk/compilers/nqp/Rules.mak   (props changed)
   trunk/compilers/pct/Rules.mak   (props changed)
   trunk/compilers/pge/Rules.mak   (props changed)
   trunk/compilers/tge/Rules.mak   (props changed)
   trunk/config/auto/sizes/intval_maxmin_c.in   (props changed)
   trunk/docs/book/draft/README   (props changed)
   trunk/docs/book/draft/appa_glossary.pod   (props changed)
   trunk/docs/book/draft/appb_patch_submission.pod   (props changed)
   trunk/docs/book/draft/appc_command_line_options.pod   (props changed)
   trunk/docs/book/draft/appd_build_options.pod   (props changed)
   trunk/docs/book/draft/appe_source_code.pod   (props changed)
   trunk/docs/book/draft/ch01_introduction.pod   (props changed)
   trunk/docs/book/draft/ch02_getting_started.pod   (props changed)
   trunk/docs/book/draft/ch07_dynpmcs.pod   (props changed)
   trunk/docs/book/draft/ch08_dynops.pod   (props changed)
   trunk/docs/book/draft/ch10_opcode_reference.pod   (props changed)
   trunk/docs/book/draft/ch11_directive_reference.pod   (props changed)
   trunk/docs/book/draft/ch12_operator_reference.pod   (props changed)
   trunk/docs/book/draft/chXX_hlls.pod   (props changed)
   trunk/docs/book/draft/chXX_library.pod   (props changed)
   trunk/docs/book/draft/chXX_testing_and_debugging.pod   (props changed)
   trunk/docs/book/pct/ch01_introduction.pod   (props changed)
   trunk/docs/book/pct/ch02_getting_started.pod   (props changed)
   trunk/docs/book/pct/ch03_compiler_tools.pod   (props changed)
   trunk/docs/book/pct/ch04_pge.pod   (props changed)
   trunk/docs/book/pct/ch05_nqp.pod   (props changed)
   trunk/docs/dev/c_functions.pod   (props changed)
   trunk/docs/pdds/pdd30_install.pod   (props changed)
   trunk/examples/embed/cotorra.c   (props changed)
   trunk/examples/languages/abc/   (props changed)
   trunk/examples/languages/squaak/   (props changed)
   trunk/examples/pge/demo.pir   (props changed)
   trunk/ext/nqp-rx/Rules.mak   (props changed)
   trunk/include/parrot/call.h   (props changed)
   trunk/include/parrot/gc_api.h   (props changed)
   trunk/include/parrot/pmc_freeze.h
   trunk/include/parrot/runcore_api.h   (props changed)
   trunk/include/parrot/runcore_profiling.h   (props changed)
   trunk/include/parrot/runcore_trace.h   (props changed)
   trunk/lib/Parrot/Configure/Step/Test.pm   (props changed)
   trunk/lib/Parrot/H2inc.pm   (props changed)
   trunk/ports/cpan/pause_guide.pod   (props changed)
   trunk/ports/cygwin/parrot-1.0.0-1.cygport   (props changed)
   trunk/ports/debian/libparrot-dev.install.in   (props changed)
   trunk/ports/debian/libparrot.install.in   (props changed)
   trunk/ports/debian/parrot-doc.install.in   (props changed)
   trunk/ports/debian/parrot.install.in   (props changed)
   trunk/ports/fedora/parrot.spec.fedora   (props changed)
   trunk/ports/mandriva/parrot.spec.mandriva   (props changed)
   trunk/ports/suse/parrot.spec.suse   (props changed)
   trunk/runtime/parrot/languages/   (props changed)
   trunk/runtime/parrot/library/Math/Rand.pir   (props changed)
   trunk/runtime/parrot/library/Math/Random/mt19937ar.pir   (props changed)
   trunk/runtime/parrot/library/Rules.mak   (props changed)
   trunk/src/call/ops.c   (props changed)
   trunk/src/call/pcc.c   (props changed)
   trunk/src/gc/alloc_memory.c   (props changed)
   trunk/src/gc/alloc_resources.c   (props changed)
   trunk/src/gc/api.c   (props changed)
   trunk/src/gc/malloc.c   (props changed)
   trunk/src/gc/malloc_trace.c   (props changed)
   trunk/src/gc/mark_sweep.c   (props changed)
   trunk/src/gc/system.c   (props changed)
   trunk/src/hash.c
   trunk/src/interp/inter_cb.c   (props changed)
   trunk/src/interp/inter_create.c   (props changed)
   trunk/src/interp/inter_misc.c   (props changed)
   trunk/src/pmc/class.pmc
   trunk/src/pmc/default.pmc
   trunk/src/pmc/eval.pmc
   trunk/src/pmc/fixedbooleanarray.pmc
   trunk/src/pmc/fixedintegerarray.pmc
   trunk/src/pmc/fixedpmcarray.pmc
   trunk/src/pmc/fixedstringarray.pmc
   trunk/src/pmc/float.pmc
   trunk/src/pmc/hash.pmc
   trunk/src/pmc/integer.pmc
   trunk/src/pmc/key.pmc
   trunk/src/pmc/lexinfo.pmc
   trunk/src/pmc/object.pmc
   trunk/src/pmc/orderedhash.pmc
   trunk/src/pmc/parrotinterpreter.pmc
   trunk/src/pmc/resizablebooleanarray.pmc
   trunk/src/pmc/resizableintegerarray.pmc
   trunk/src/pmc/scheduler.pmc
   trunk/src/pmc/schedulermessage.pmc
   trunk/src/pmc/string.pmc
   trunk/src/pmc/sub.pmc
   trunk/src/pmc/task.pmc
   trunk/src/pmc_freeze.c
   trunk/src/runcore/cores.c   (props changed)
   trunk/src/runcore/main.c   (props changed)
   trunk/src/runcore/profiling.c   (props changed)
   trunk/src/runcore/trace.c   (props changed)
   trunk/src/vtable.tbl
   trunk/t/compilers/tge/NoneGrammar.tg   (props changed)
   trunk/t/library/mt19937ar.t   (props changed)
   trunk/t/library/mt19937ar.txt   (props changed)
   trunk/t/native_pbc/annotations.pbc
   trunk/t/native_pbc/integer_1.pbc
   trunk/t/native_pbc/number_1.pbc
   trunk/t/native_pbc/string_1.pbc
   trunk/t/oo/root_new.t   (props changed)
   trunk/t/pmc/namespace-old.t   (props changed)
   trunk/t/src/embed.t   (props changed)
   trunk/t/steps/init/hints/linux-01.t   (props changed)
   trunk/tools/build/cc_flags.pl   (props changed)
   trunk/tools/build/h2inc.pl   (props changed)
   trunk/tools/dev/fetch_languages.pl   (props changed)
   trunk/tools/dev/mk_gitignore.pl   (props changed)
   trunk/tools/util/perlcritic-cage.conf   (props changed)

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/MANIFEST	Tue Feb  2 19:38:35 2010	(r43706)
@@ -1428,6 +1428,7 @@
 src/pmc/hash.pmc                                            [devel]src
 src/pmc/hashiterator.pmc                                    [devel]src
 src/pmc/hashiteratorkey.pmc                                 [devel]src
+src/pmc/imageio.pmc                                         [devel]src
 src/pmc/integer.pmc                                         [devel]src
 src/pmc/iterator.pmc                                        [devel]src
 src/pmc/key.pmc                                             [devel]src

Modified: trunk/PBC_COMPAT
==============================================================================
--- trunk/PBC_COMPAT	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/PBC_COMPAT	Tue Feb  2 19:38:35 2010	(r43706)
@@ -27,6 +27,7 @@
 
 # please insert tab separated entries at the top of the list
 
+6.2	2010.01.31	cotto	serialization-related changes to ParrotInterpreter
 6.1	2010.01.30	whiteknight	remove Array PMC
 6.0	2010.01.19	chromatic	released 2.0.0
 5.1	2009.08.06	cotto	remove branch_cs opcode

Modified: trunk/include/parrot/pmc_freeze.h
==============================================================================
--- trunk/include/parrot/pmc_freeze.h	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/include/parrot/pmc_freeze.h	Tue Feb  2 19:38:35 2010	(r43706)
@@ -14,7 +14,7 @@
 #define PARROT_PMC_FREEZE_H_GUARD
 
 struct _visit_info;
-typedef void (*visit_f)(PARROT_INTERP, ARGIN_NULLOK(PMC*), ARGIN(struct _visit_info*));
+typedef void (*visit_f)(PARROT_INTERP, ARGIN_NULLOK(PMC*), ARGIN(PMC*));
 
 typedef enum {
     VISIT_HOW_PMC_TO_VISITOR     = 0x00, /* push to visitor */
@@ -40,53 +40,11 @@
 #define VISIT_THAW_NORMAL    (VISIT_HOW_VISITOR_TO_PMC | VISIT_WHAT_PMC)
 #define VISIT_THAW_CONSTANTS VISIT_THAW_NORMAL
 
-struct _visit_info;
-typedef INTVAL   (*get_integer_f)   (PARROT_INTERP, struct _visit_info*);
-typedef void     (*push_integer_f)  (PARROT_INTERP, struct _visit_info*, INTVAL);
-typedef void     (*push_string_f)   (PARROT_INTERP, struct _visit_info*, STRING*);
-typedef void     (*push_number_f)   (PARROT_INTERP, struct _visit_info*, FLOATVAL);
-typedef void     (*push_pmc_f)      (PARROT_INTERP, struct _visit_info*, PMC*);
-typedef INTVAL   (*shift_integer_f) (PARROT_INTERP, struct _visit_info*);
-typedef STRING*  (*shift_string_f)  (PARROT_INTERP, struct _visit_info*);
-typedef FLOATVAL (*shift_number_f)  (PARROT_INTERP, struct _visit_info*);
-typedef PMC*     (*shift_pmc_f)     (PARROT_INTERP, struct _visit_info*);
-
-typedef struct _image_funcs {
-    get_integer_f       get_integer;
-    push_integer_f      push_integer;
-    push_string_f       push_string;
-    push_number_f       push_float;
-    push_pmc_f          push_pmc;
-    shift_integer_f     shift_integer;
-    shift_string_f      shift_string;
-    shift_number_f      shift_float;
-    shift_pmc_f         shift_pmc;
-} image_funcs;
-
 typedef enum {
     EXTRA_IS_NULL,
     EXTRA_IS_PROP_HASH,
 } extra_flags_enum;
 
-typedef struct _visit_info {
-    visit_f             visit_pmc_now;
-    size_t              pos;            /* current read/write position in buffer */
-    Buffer             *buffer;
-    size_t              input_length;   /* */
-    INTVAL              what;
-    PMC               **thaw_ptr;       /* where to thaw a new PMC */
-    PMC                *seen;           /* seen hash */
-    PMC                *todo;           /* todo list */
-    PMC                *id_list;        /* seen list used by thaw */
-    UINTVAL             id;             /* freze ID of PMC */
-    INTVAL              extra_flags;    /* concerning to extra */
-    struct PackFile    *pf;
-    const image_funcs  *vtable;
-    struct _visit_info *image_io;       /* dummy backwards-compat pointer. */
-} visit_info;
-
-#define IMAGE_IO visit_info
-
 #define VISIT_PMC(interp, visit, pmc) do {\
     const INTVAL _visit_pmc_flags = VTABLE_get_integer((interp), (visit)); \
     if (_visit_pmc_flags & VISIT_WHAT_PMC) { \

Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/hash.c	Tue Feb  2 19:38:35 2010	(r43706)
@@ -55,7 +55,7 @@
 
 static void hash_freeze(PARROT_INTERP,
     ARGIN(const Hash * const hash),
-    ARGMOD(visit_info *info))
+    ARGMOD(PMC *info))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
@@ -63,7 +63,7 @@
 
 static void hash_thaw(PARROT_INTERP,
     ARGMOD(Hash *hash),
-    ARGMOD(visit_info *info))
+    ARGMOD(PMC *info))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
@@ -541,7 +541,7 @@
 
 /*
 
-=item C<static void hash_thaw(PARROT_INTERP, Hash *hash, visit_info *info)>
+=item C<static void hash_thaw(PARROT_INTERP, Hash *hash, PMC *info)>
 
 Visits the contents of a hash during freeze/thaw.
 
@@ -552,7 +552,7 @@
 */
 
 static void
-hash_thaw(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(visit_info *info))
+hash_thaw(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(PMC *info))
 {
     ASSERT_ARGS(hash_thaw)
 
@@ -608,8 +608,8 @@
 
 /*
 
-=item C<static void hash_freeze(PARROT_INTERP, const Hash * const hash,
-visit_info *info)>
+=item C<static void hash_freeze(PARROT_INTERP, const Hash * const hash, PMC
+*info)>
 
 Freezes hash into a string.
 
@@ -623,7 +623,7 @@
 */
 
 static void
-hash_freeze(PARROT_INTERP, ARGIN(const Hash * const hash), ARGMOD(visit_info *info))
+hash_freeze(PARROT_INTERP, ARGIN(const Hash * const hash), ARGMOD(PMC *info))
 {
     ASSERT_ARGS(hash_freeze)
     size_t           i;
@@ -677,7 +677,7 @@
 parrot_hash_visit(PARROT_INTERP, ARGMOD(Hash *hash), ARGMOD(void *pinfo))
 {
     ASSERT_ARGS(parrot_hash_visit)
-    visit_info* const info = (visit_info*) pinfo;
+    PMC* const info = (PMC*) pinfo;
 
     switch (VTABLE_get_integer(interp, info)) {
       case VISIT_THAW_NORMAL:

Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/class.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -1421,7 +1421,7 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the class.
 
@@ -1431,7 +1431,7 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         /* 1) visit the attribute description hash */
         VISIT_PMC_ATTR(INTERP, info, SELF, Class, attrib_metadata);
 
@@ -1453,7 +1453,7 @@
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the class.
 
@@ -1461,7 +1461,7 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         Parrot_Class_attributes * const class_data = PARROT_CLASS(SELF);
         STRING       *serial_namespace = CONST_STRING(interp, "");
 
@@ -1483,7 +1483,7 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the class.
 
@@ -1491,7 +1491,7 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         /* The class might already exist in the interpreter, so create it as an
          * anonymous class and later decide whether to link it into the
          * namespace.  */
@@ -1549,7 +1549,7 @@
 
 /*
 
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
 
 Called after the class has been thawed.
 
@@ -1557,7 +1557,7 @@
 
 */
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         Parrot_Class_attributes * const _class = PARROT_CLASS(SELF);
         UNUSED(info)
 

Modified: trunk/src/pmc/default.pmc
==============================================================================
--- trunk/src/pmc/default.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/default.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -1043,7 +1043,7 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 Used by GC to mark the PMC.
 
@@ -1051,7 +1051,7 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
     }
 
 /*
@@ -1070,7 +1070,7 @@
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Does nothing.
 
@@ -1078,14 +1078,14 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         UNUSED(info)
         /* default - no action */
     }
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Initializes the PMC during unarchiving.
 
@@ -1093,14 +1093,14 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         /* default - initialize the PMC */
         SELF.init();
     }
 
 /*
 
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
 
 Does nothing.
 
@@ -1108,7 +1108,7 @@
 
 */
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         UNUSED(info)
         /* default - no action */
     }

Modified: trunk/src/pmc/eval.pmc
==============================================================================
--- trunk/src/pmc/eval.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/eval.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -320,11 +320,11 @@
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Archives the evaled code
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Unarchives the code.
 
@@ -332,14 +332,14 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         STRING   *packed = SELF.get_string();
         VTABLE_push_string(INTERP, info, packed);
 
         SUPER(info);
     }
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         STRING           *packed = VTABLE_shift_string(INTERP, info);
         PackFile         *pf;
         PackFile_Segment *seg;

Modified: trunk/src/pmc/fixedbooleanarray.pmc
==============================================================================
--- trunk/src/pmc/fixedbooleanarray.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/fixedbooleanarray.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -506,14 +506,14 @@
 
 =over 4
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the string.
 
 =cut
 
 */
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         UINTVAL          size, resize_threshold;
         unsigned char  * bit_array;
         STRING   *       s;
@@ -530,14 +530,14 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the string.
 
 =cut
 
 */
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         SUPER(info);
 
         {

Modified: trunk/src/pmc/fixedintegerarray.pmc
==============================================================================
--- trunk/src/pmc/fixedintegerarray.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/fixedintegerarray.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -537,17 +537,17 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the array.
 
 C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the array.
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the array.
 
@@ -555,11 +555,11 @@
 
 */
 
-    /*VTABLE void visit(visit_info *info) {
+    /*VTABLE void visit(PMC *info) {
         SUPER(info);
     }*/
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         INTVAL   *int_array;
         INTVAL    i, n;
 
@@ -573,7 +573,7 @@
             VTABLE_push_integer(INTERP, info, int_array[i]);
     }
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         INTVAL n;
 
         SUPER(info);

Modified: trunk/src/pmc/fixedpmcarray.pmc
==============================================================================
--- trunk/src/pmc/fixedpmcarray.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/fixedpmcarray.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -690,17 +690,17 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the array.
 
 C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the array.
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the array.
 
@@ -708,25 +708,24 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         INTVAL  i;
         const INTVAL n = VTABLE_elements(INTERP, SELF);
         PMC   **pos    = PMC_array(SELF);
 
         for (i = 0; i < n; ++i, ++pos) {
-            info->thaw_ptr = pos;
-            (info->visit_pmc_now)(INTERP, *pos, info);
+            VISIT_PMC(INTERP, info, *pos);
         }
 
         SUPER(info);
     }
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         SUPER(info);
         VTABLE_push_integer(INTERP, info, VTABLE_elements(INTERP, SELF));
     }
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         SUPER(info);
         SELF.set_integer_native(VTABLE_shift_integer(INTERP, info));
     }

Modified: trunk/src/pmc/fixedstringarray.pmc
==============================================================================
--- trunk/src/pmc/fixedstringarray.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/fixedstringarray.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -559,14 +559,14 @@
 
 =over 4
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the string.
 
 =cut
 
 */
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         STRING           **str_array;
         UINTVAL            size, i;
 
@@ -580,14 +580,14 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the string.
 
 =cut
 
 */
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         UINTVAL  i, size;
         STRING **str_array;
 

Modified: trunk/src/pmc/float.pmc
==============================================================================
--- trunk/src/pmc/float.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/float.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -344,28 +344,28 @@
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the number.
 
 =cut
 
 */
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         SUPER(info);
         VTABLE_push_float(INTERP, info, SELF.get_number());
     }
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the number.
 
 =cut
 
 */
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         SUPER(info);
         SET_ATTR_fv(INTERP, SELF, VTABLE_shift_float(INTERP, info));
     }

Modified: trunk/src/pmc/hash.pmc
==============================================================================
--- trunk/src/pmc/hash.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/hash.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -1078,7 +1078,7 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 Used during archiving to visit the elements in the hash.
 
@@ -1086,14 +1086,14 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         parrot_hash_visit(INTERP, (Hash *)SELF.get_pointer(), info);
         SUPER(info);
     }
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the hash.
 
@@ -1101,7 +1101,7 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         Hash     * const hash = (Hash *)SELF.get_pointer();;
 
         SUPER(info);
@@ -1112,7 +1112,7 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the hash.
 
@@ -1120,7 +1120,7 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         SUPER(info);
 
         {

Copied: trunk/src/pmc/imageio.pmc (from r43704, branches/pmc_freeze_with_pmcs/src/pmc/imageio.pmc)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/pmc/imageio.pmc	Tue Feb  2 19:38:35 2010	(r43706, copy of r43704, branches/pmc_freeze_with_pmcs/src/pmc/imageio.pmc)
@@ -0,0 +1,590 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/imageio.pmc - ImageIO PMC
+
+=head1 DESCRIPTION
+
+Freezes and thaws other PMCs.
+
+*/
+
+#define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
+
+/* when thawing a string longer then this size, we first do a GC run and then
+ * block GC - the system can't give us more headers */
+
+#define THAW_BLOCK_GC_SIZE 100000
+
+/* preallocate freeze image for aggregates with this estimation */
+#define FREEZE_BYTES_PER_ITEM 9
+
+/* macros/constants to handle packing/unpacking of PMC IDs and flags
+ * the 2 LSBs are used for flags, all other bits are used for PMC ID
+ */
+#define PackID_new(id, flags)       (((UINTVAL)(id) * 4) | ((UINTVAL)(flags) & 3))
+#define PackID_get_PMCID(id)        ((UINTVAL)(id) / 4)
+#define PackID_set_PMCID(lv, id)    (lv) = PackID_new((id), PackID_get_FLAGS(lv))
+#define PackID_get_FLAGS(id)        ((UINTVAL)(id) & 3)
+#define PackID_set_FLAGS(lv, flags) (lv) = PackID_new(PackID_get_PMCID(lv), (flags))
+
+enum {
+    enum_PackID_normal     = 0,
+    enum_PackID_seen       = 1,
+};
+
+PARROT_INLINE
+static opcode_t *
+GET_VISIT_CURSOR(PMC *pmc){
+    char  *buf = (char *)Buffer_bufstart(PARROT_IMAGEIO(pmc)->buffer);
+    size_t pos = PARROT_IMAGEIO(pmc)->pos;
+    return (opcode_t *)(buf + pos);
+}
+
+PARROT_INLINE
+static void
+SET_VISIT_CURSOR(PMC *pmc, char *cursor) {
+    char *bufstart  = (char *)Buffer_bufstart(PARROT_IMAGEIO(pmc)->buffer);
+    PARROT_IMAGEIO(pmc)->pos = (cursor - bufstart);
+}
+
+PARROT_INLINE
+static void
+INC_VISIT_CURSOR(PMC *pmc, UINTVAL inc) {
+    PARROT_IMAGEIO(pmc)->pos += inc;
+}
+
+#define BYTECODE_SHIFT_OK(pmc) PARROT_ASSERT( \
+    PARROT_IMAGEIO(pmc)->pos <= PARROT_IMAGEIO(pmc)->input_length)
+
+
+
+static void
+create_buffer(PARROT_INTERP, PMC *pmc, PMC *info)
+{
+    INTVAL  len;
+
+    if (!PMC_IS_NULL(pmc)) {
+        STRING *array = CONST_STRING(interp, "array");
+        STRING *hash  = CONST_STRING(interp, "hash");
+        INTVAL  items = 1;
+
+        if (VTABLE_does(interp, pmc, array) || VTABLE_does(interp, pmc, hash)) {
+            items += VTABLE_elements(interp, pmc);
+        }
+        len = items * FREEZE_BYTES_PER_ITEM;
+    }
+    else
+        len = FREEZE_BYTES_PER_ITEM;
+
+    PARROT_IMAGEIO(info)->buffer =
+        (Buffer *)Parrot_gc_new_bufferlike_header(interp, sizeof (Buffer));
+    Parrot_gc_allocate_buffer_storage_aligned(interp,
+        PARROT_IMAGEIO(info)->buffer, len);
+    SET_VISIT_CURSOR(info, (char *)Buffer_bufstart(PARROT_IMAGEIO(info)->buffer));
+}
+
+
+/*
+static void ensure_buffer_size(PARROT_INTERP, PMC *io, size_t len)
+
+Checks the size of the buffer to see if it can accommodate 'len' more
+bytes. If not, expands the buffer.
+
+*/
+
+PARROT_INLINE
+static void
+ensure_buffer_size(PARROT_INTERP, ARGIN(PMC *io), size_t len)
+{
+    Buffer *buf         = PARROT_IMAGEIO(io)->buffer;
+    const size_t used   = PARROT_IMAGEIO(io)->pos;
+    const int need_free = Buffer_buflen(buf) - used - len;
+
+    /* grow by factor 1.5 or such */
+    if (need_free <= 16) {
+        size_t new_size = (size_t) (Buffer_buflen(buf) * 1.5);
+        if (new_size < Buffer_buflen(buf) - need_free + 512)
+            new_size = Buffer_buflen(buf) - need_free + 512;
+        Parrot_gc_reallocate_buffer_storage(interp, buf, new_size);
+        PARROT_ASSERT(Buffer_buflen(buf) - used - len >= 15);
+    }
+
+#ifndef DISABLE_GC_DEBUG
+    Parrot_gc_compact_memory_pool(INTERP);
+#endif
+
+}
+
+PARROT_INLINE
+static INTVAL
+INFO_HAS_DATA(ARGIN(PMC *io)) {
+    return PARROT_IMAGEIO(io)->pos < PARROT_IMAGEIO(io)->input_length;
+}
+
+PARROT_INLINE
+static PMC*
+id_list_get(PARROT_INTERP, PMC *io, UINTVAL id) {
+    return VTABLE_get_pmc_keyed_int(interp, PARROT_IMAGEIO(io)->id_list, id);
+}
+
+PARROT_INLINE
+static void
+visit_todo_list_thaw(PARROT_INTERP, SHIM(PMC* pmc_not_used), ARGIN(PMC* info))
+{
+    UINTVAL  n            = VTABLE_shift_integer(interp, info);
+    UINTVAL  id           = PackID_get_PMCID(n);
+    int      packid_flags = PackID_get_FLAGS(n);
+    PMC     *pmc          = PMCNULL;
+
+    PARROT_ASSERT(PARROT_IMAGEIO(info)->what == VISIT_THAW_NORMAL);
+
+    switch (packid_flags) {
+      case enum_PackID_seen:
+        if (id) /* got a non-NULL PMC */
+            pmc = id_list_get(interp, info, id);
+        break;
+      case enum_PackID_normal:
+        {
+            INTVAL type = VTABLE_shift_integer(interp, info);
+            if (type <= 0 || type > interp->n_vtable_max)
+                Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown PMC type to thaw %d", type);
+
+            pmc = pmc_new_noinit(interp, type);
+            VTABLE_thaw(interp, pmc, info);
+
+            {
+                PMC * const todo    = PARROT_IMAGEIO(info)->todo;
+                PMC * const id_list = PARROT_IMAGEIO(info)->id_list;
+                VTABLE_set_pmc_keyed_int(interp, id_list, id, pmc);
+                /* remember nested aggregates depth first */
+                VTABLE_unshift_pmc(interp, todo, pmc);
+            }
+        }
+        break;
+      default:
+        Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown PMC id args thaw %d", packid_flags);
+        break;
+    }
+
+    *(PARROT_IMAGEIO(info)->thaw_ptr) = pmc;
+}
+
+static void
+visit_todo_list_freeze(PARROT_INTERP, PMC* pmc, PMC* info)
+{
+    UINTVAL id;
+    int packid_type;
+
+    PARROT_ASSERT(PARROT_IMAGEIO(info)->what == VISIT_FREEZE_NORMAL);
+
+    if (PMC_IS_NULL(pmc)) {
+        id   = 0;
+        packid_type = enum_PackID_seen;
+    }
+    else {
+        Hash *hash = (Hash *)VTABLE_get_pointer(interp, PARROT_IMAGEIO(info)->seen);
+        HashBucket * const b = parrot_hash_get_bucket(interp, hash, pmc);
+        if (b) {
+            id = (UINTVAL) b->value;
+            packid_type = enum_PackID_seen;
+        }
+        else {
+            PARROT_IMAGEIO(info)->id++; /* next id to freeze */
+            id = PARROT_IMAGEIO(info)->id;
+            packid_type = enum_PackID_normal;
+        }
+    }
+
+    VTABLE_push_integer(interp, info, PackID_new(id, packid_type));
+
+    if (packid_type == enum_PackID_normal) {
+        Hash *hash = (Hash *)VTABLE_get_pointer(interp, PARROT_IMAGEIO(info)->seen);
+        PARROT_ASSERT(pmc);
+        VTABLE_push_integer(interp, info,
+                PObj_is_object_TEST(pmc) ? enum_class_Object : pmc->vtable->base_type);
+        parrot_hash_put(interp, hash, pmc, (void *)id);
+        VTABLE_unshift_pmc(interp, PARROT_IMAGEIO(info)->todo, pmc);
+        VTABLE_freeze(interp, pmc, info);
+    }
+}
+
+static void
+visit_loop_todo_list(PARROT_INTERP, PMC *current, PMC *info)
+{
+    PMC * const todo     = PARROT_IMAGEIO(info)->todo;
+    const int    thawing = PARROT_IMAGEIO(info)->what == VISIT_THAW_NORMAL;
+
+    (PARROT_IMAGEIO(info)->visit_pmc_now)(interp, current, info);
+
+    /* can't cache upper limit, visit may append items */
+    while (VTABLE_get_bool(interp, todo)) {
+        current = VTABLE_shift_pmc(interp, todo);
+        if (!current)
+            Parrot_ex_throw_from_c_args(interp, NULL, 1,
+                    "NULL current PMC in visit_loop_todo_list");
+
+        PARROT_ASSERT(current->vtable);
+
+        VTABLE_visit(interp, current, info);
+
+        VISIT_PMC(interp, info, PMC_metadata(current));
+    }
+
+    if (thawing)
+        /* we're done reading the image */
+        PARROT_ASSERT(!INFO_HAS_DATA(info));
+
+    if (thawing) {
+        /* on thawing call thawfinish for each processed PMC */
+        const INTVAL n = VTABLE_elements(interp, PARROT_IMAGEIO(info)->id_list);
+        int          i;
+
+        /*
+         * Thaw in reverse order. We have to fully thaw younger PMCs
+         * before use them in older.
+         *
+         * XXX There are no younger or older pmcs in a directed graph
+         *     that allows cycles. Any code that requires a specific
+         *      order here is likely broken.
+         */
+        for (i = n-1; i >= 0; --i) {
+            current = VTABLE_get_pmc_keyed_int(interp, PARROT_IMAGEIO(info)->id_list, i);
+            if (!PMC_IS_NULL(current))
+                VTABLE_thawfinish(interp, current, info);
+        }
+    }
+}
+
+pmclass ImageIO auto_attrs {
+    ATTR visit_f          visit_pmc_now;
+    ATTR Buffer          *buffer;         /* buffer to store the image */
+    ATTR size_t           pos;            /* current read/write position in buffer */
+    ATTR size_t           input_length;
+    ATTR INTVAL           what;
+    ATTR PMC            **thaw_ptr;       /* where to thaw a new PMC */
+    ATTR PMC             *seen;           /* seen hash */
+    ATTR PMC             *todo;           /* todo list */
+    ATTR PMC             *id_list;        /* seen list used by thaw */
+    ATTR UINTVAL          id;             /* freze ID of PMC */
+    ATTR INTVAL           extra_flags;    /* concerning to extra */
+    ATTR struct PackFile *pf;
+
+/*
+
+=head1 VTABLES
+
+=over 4
+
+=cut
+
+*/
+
+/*
+
+=item C<void init()>
+
+Initializes the PMC.
+
+=cut
+
+*/
+    VTABLE void init() {
+        PARROT_IMAGEIO(SELF)->thaw_ptr    = NULL;
+        PARROT_IMAGEIO(SELF)->buffer      = NULL;
+        PARROT_IMAGEIO(SELF)->todo        = pmc_new(INTERP, enum_class_ResizablePMCArray);
+        PARROT_IMAGEIO(SELF)->seen        = PMCNULL;
+        PARROT_IMAGEIO(SELF)->id_list     = PMCNULL;
+        PARROT_IMAGEIO(SELF)->id          = 0;
+        PARROT_IMAGEIO(SELF)->extra_flags = EXTRA_IS_NULL;
+        PARROT_IMAGEIO(SELF)->pf          = PackFile_new(INTERP, 0);
+
+        PObj_custom_mark_destroy_SETALL(SELF);
+    }
+
+
+/*
+
+=item C<void destroy()>
+
+Destroys the PMC.
+
+=cut
+
+*/
+    VTABLE void destroy() {
+        PackFile_destroy(INTERP, PARROT_IMAGEIO(SELF)->pf);
+    }
+
+/*
+
+=item C<void mark()>
+
+Marks the PMC as alive.
+
+=cut
+
+*/
+    VTABLE void mark() {
+        Parrot_gc_mark_PObj_alive(INTERP, (PObj *)(PARROT_IMAGEIO(SELF)->buffer));
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->todo);
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->seen);
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->id_list);
+    }
+
+/*
+
+=item C<STRING *get_string()>
+
+Returns the content of the image as a string.
+
+=cut
+
+*/
+
+    VTABLE STRING *get_string() {
+        return Parrot_str_new_from_buffer(INTERP,
+                                          PARROT_IMAGEIO(SELF)->buffer,
+                                          PARROT_IMAGEIO(SELF)->pos);
+    }
+/*
+
+/*
+
+=item C<VTABLE void set_pointer()>
+
+Sets the location where to thaw a new PMC.
+
+=cut
+
+*/
+
+VTABLE void set_pointer(void* value) {
+    PARROT_IMAGEIO(SELF)->thaw_ptr = value;
+}
+
+/*
+
+=item C<VTABLE INTVAL get_integer()>
+
+Returns the flags describing the visit action
+
+=cut
+
+*/
+
+VTABLE INTVAL get_integer() {
+    return PARROT_IMAGEIO(SELF)->what;
+}
+
+/*
+
+=item C<VTABLE void push_integer(INTVAL v)>
+
+Pushes the integer C<v> onto the end of the image.
+
+=cut
+
+*/
+
+VTABLE void push_integer(INTVAL v) {
+    size_t len = PF_size_integer() * sizeof (opcode_t);
+    ensure_buffer_size(interp, SELF, len);
+    SET_VISIT_CURSOR(SELF, (char *)PF_store_integer(GET_VISIT_CURSOR(SELF), v));
+}
+
+
+/*
+
+=item C<VTABLE void push_float(FLOATVAL v)>
+
+Pushes the float C<v> onto the end of the image.
+
+=cut
+
+*/
+
+VTABLE void push_float(FLOATVAL v)
+{
+    size_t len = PF_size_number() * sizeof (opcode_t);
+    ensure_buffer_size(interp, SELF, len);
+    SET_VISIT_CURSOR(SELF, (char *)PF_store_number(GET_VISIT_CURSOR(SELF), &v));
+}
+
+
+/*
+
+=item C<VTABLE void push_string(STRING *v)>
+
+Pushes the string C<*v> onto the end of the image.
+
+=cut
+
+*/
+
+VTABLE void push_string(STRING *v)
+{
+    size_t len = PF_size_string(v) * sizeof (opcode_t);
+    ensure_buffer_size(INTERP, SELF, len);
+    SET_VISIT_CURSOR(SELF, (char *)PF_store_string(GET_VISIT_CURSOR(SELF), v));
+}
+
+/*
+
+=item C<VTABLE void push_pmc(PMC *v)>
+
+Pushes a reference to pmc C<*v> onto the end of the image. If C<*v>
+hasn't been seen yet, it is also pushed onto the todo list.
+
+=cut
+
+*/
+
+VTABLE void push_pmc(PMC *v) {
+    VTABLE_set_pointer(interp, SELF, &v);
+    (PARROT_IMAGEIO(SELF)->visit_pmc_now)(INTERP, v, SELF);
+}
+
+/*
+
+=item C<VTABLE INTVAL shift_integer()>
+
+Removes and returns an integer from the start of the image.
+
+=cut
+
+*/
+
+VTABLE INTVAL shift_integer()
+{
+    opcode_t *pos  = GET_VISIT_CURSOR(SELF);
+    const INTVAL i = PF_fetch_integer(PARROT_IMAGEIO(SELF)->pf, (const opcode_t **)&pos);
+    SET_VISIT_CURSOR(SELF, (char *)pos);
+    BYTECODE_SHIFT_OK(SELF);
+    return i;
+}
+
+
+/*
+
+=item C<VTABLE FLOATVAL shift_float()>
+
+Removes and returns an number from the start of the image.
+
+=cut
+
+*/
+
+VTABLE FLOATVAL shift_float() {
+    opcode_t *pos    = GET_VISIT_CURSOR(SELF);
+    const FLOATVAL f = PF_fetch_number(PARROT_IMAGEIO(SELF)->pf, (const opcode_t **)&pos);
+    SET_VISIT_CURSOR(SELF, (char *)pos);
+    BYTECODE_SHIFT_OK(SELF);
+    return f;
+}
+
+
+/*
+
+=item C<VTABLE STRING* shift_string()>
+
+Removes and returns a string from the start of the image.
+
+=cut
+
+*/
+
+VTABLE STRING *shift_string()
+{
+    opcode_t *pos    = GET_VISIT_CURSOR(SELF);
+    STRING * const s = PF_fetch_string(interp, PARROT_IMAGEIO(SELF)->pf, (const opcode_t **)&pos);
+    SET_VISIT_CURSOR(SELF, (char *)pos);
+    BYTECODE_SHIFT_OK(SELF);
+    return s;
+}
+
+/*
+
+=item C<static PMC *shift_pmc()>
+
+Removes and returns a reference to a pmc from the start of the image.
+
+=cut
+
+*/
+
+VTABLE PMC *shift_pmc() {
+    PMC *result;
+    VTABLE_set_pointer(interp, SELF, &result);
+    (PARROT_IMAGEIO(SELF)->visit_pmc_now)(interp, NULL, SELF);
+    return result;
+}
+
+VTABLE void set_pmc(PMC *p)
+{
+        UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+
+        PARROT_IMAGEIO(SELF)->what = VISIT_FREEZE_NORMAL;
+        PARROT_IMAGEIO(SELF)->visit_pmc_now  = visit_todo_list_freeze;
+        create_buffer(INTERP, p, SELF);
+        ensure_buffer_size(INTERP, SELF, header_length);
+        mem_sys_memcopy(GET_VISIT_CURSOR(SELF),
+            PARROT_IMAGEIO(SELF)->pf->header, PACKFILE_HEADER_BYTES);
+        INC_VISIT_CURSOR(SELF, header_length);
+
+        PARROT_IMAGEIO(SELF)->seen = pmc_new(INTERP, enum_class_Hash);
+        VTABLE_set_pointer(INTERP, PARROT_IMAGEIO(SELF)->seen,
+            parrot_new_intval_hash(INTERP));
+
+        visit_loop_todo_list(INTERP, p, SELF);
+}
+
+VTABLE void set_string_native(STRING *image) {
+        UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+        int unpacked_length;
+
+        PARROT_IMAGEIO(SELF)->what          = VISIT_THAW_NORMAL;
+        PARROT_IMAGEIO(SELF)->visit_pmc_now = visit_todo_list_thaw;
+        PARROT_IMAGEIO(SELF)->buffer        = (Buffer *)image;
+        PARROT_IMAGEIO(SELF)->id_list       = pmc_new(INTERP, enum_class_ResizablePMCArray);
+
+        PARROT_ASSERT(image->_bufstart == image->strstart);
+
+        SET_VISIT_CURSOR(SELF, (char *)Buffer_bufstart(PARROT_IMAGEIO(SELF)->buffer));
+        PARROT_IMAGEIO(SELF)->input_length = image->strlen;
+
+        PARROT_IMAGEIO(SELF)->pf->options |= PFOPT_PMC_FREEZE_ONLY;
+        unpacked_length = PackFile_unpack(interp, PARROT_IMAGEIO(SELF)->pf,
+            GET_VISIT_CURSOR(SELF), PARROT_IMAGEIO(SELF)->input_length);
+
+        if (!unpacked_length) {
+            Parrot_ex_throw_from_c_args(interp, NULL,
+                    EXCEPTION_INVALID_STRING_REPRESENTATION,
+                    "PackFile header failed during unpack");
+        }
+        else {
+            INC_VISIT_CURSOR(SELF, header_length);
+        }
+
+        visit_loop_todo_list(interp, pmc, SELF);
+}
+
+/*
+
+=back
+
+=cut
+
+*/
+
+}
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: trunk/src/pmc/integer.pmc
==============================================================================
--- trunk/src/pmc/integer.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/integer.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -1304,14 +1304,14 @@
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the integer.
 
 =cut
 
 */
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         SUPER(info);
         VTABLE_push_integer(INTERP, info, SELF.get_integer());
     }
@@ -1319,14 +1319,14 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the integer.
 
 =cut
 
 */
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         SUPER(info);
         SELF.set_integer_native(VTABLE_shift_integer(INTERP, info));
     }

Modified: trunk/src/pmc/key.pmc
==============================================================================
--- trunk/src/pmc/key.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/key.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -283,19 +283,19 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the Key.
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Archives the Key.
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Unarchives the Key.
 
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
 
 Called after the Key has been thawed: convert last PMC_NULL key to NULL.
 
@@ -303,7 +303,7 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         /* Sometimes visit gets an uninitialized Key.  Initialize it. */
         if (!PMC_data(SELF))
             SELF.init();
@@ -311,7 +311,7 @@
         VISIT_PMC_ATTR(INTERP, info, SELF, Key, next_key);
     }
 
-    void freeze(visit_info *info) {
+    void freeze(PMC *info) {
         /* write flags */
         const INTVAL flags  = (PObj_get_FLAGS(SELF) & KEY_type_FLAGS);
 
@@ -340,7 +340,7 @@
         }
     }
 
-    void thaw(visit_info *info) {
+    void thaw(PMC *info) {
         const INTVAL flags  = VTABLE_shift_integer(INTERP, info) & KEY_type_FLAGS;
 
         PObj_get_FLAGS(SELF) |= flags;
@@ -367,7 +367,7 @@
         }
     }
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         PMC *key = SELF;
         UNUSED(info)
 

Modified: trunk/src/pmc/lexinfo.pmc
==============================================================================
--- trunk/src/pmc/lexinfo.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/lexinfo.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -125,11 +125,11 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Freeze/thaw interface used during freeze/thaw of the Sub PMC.
 The implementation of the Hash PMC is called.
@@ -139,7 +139,7 @@
 */
 
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         const INTVAL elems  = VTABLE_shift_integer(INTERP, info);
         const INTVAL k_type = VTABLE_shift_integer(INTERP, info);
         const INTVAL v_type = VTABLE_shift_integer(INTERP, info);

Modified: trunk/src/pmc/object.pmc
==============================================================================
--- trunk/src/pmc/object.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/object.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -725,7 +725,7 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the object.
 
@@ -735,24 +735,19 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         Parrot_Object_attributes * const obj_data = PARROT_OBJECT(SELF);
-        PMC **pos;
 
         /* 1) visit class */
-        pos            = &obj_data->_class;
-        info->thaw_ptr = pos;
-        (info->visit_pmc_now)(INTERP, *pos, info);
+        VISIT_PMC(INTERP, info, obj_data->_class);
 
         /* 2) visit the attributes */
-        pos      = &obj_data->attrib_store;
-        info->thaw_ptr = pos;
-        (info->visit_pmc_now)(INTERP, *pos, info);
+        VISIT_PMC(INTERP, info, obj_data->attrib_store);
     }
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the object.
 
@@ -760,13 +755,13 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         return;
     }
 
 /*
 
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
 
 Called after the object has been thawed.
 
@@ -774,7 +769,7 @@
 
 */
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         /* Set custom GC mark and destroy on the object. */
         PObj_custom_mark_SET(SELF);
         PObj_custom_destroy_SET(SELF);

Modified: trunk/src/pmc/orderedhash.pmc
==============================================================================
--- trunk/src/pmc/orderedhash.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/orderedhash.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -726,15 +726,15 @@
     }
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 Used during archiving to visit the elements in the hash.
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the hash.
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the hash.
 
@@ -742,12 +742,12 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         VISIT_PMC_ATTR(INTERP, info, SELF, OrderedHash, hash);
         SUPER(info);
     }
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         Parrot_OrderedHash_attributes *attrs = PARROT_ORDEREDHASH(SELF);
         find_bounds(INTERP, attrs->hash, &attrs->first, &attrs->last);
         SUPER(info);

Modified: trunk/src/pmc/parrotinterpreter.pmc
==============================================================================
--- trunk/src/pmc/parrotinterpreter.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/parrotinterpreter.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -658,24 +658,24 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the interpreter.
 
 C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the interpreter. Actually not the whole interpreter is
 frozen but the state of the interpreter, which includes everything that
 has changes since creating an empty interpreter.
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the interpreter. This merges the changes into this
 interpreter instance.
 
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
 
 Finish thawing.
 
@@ -683,8 +683,7 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
-        PMC **pos;
+    VTABLE void visit(PMC *info) {
         /*
          * the information frozen here is part of all PBCs
          * we probably need to freeze all dynamic extensible
@@ -710,16 +709,14 @@
         /*  HLL_info */
         if (VTABLE_get_integer(INTERP, info) == VISIT_THAW_NORMAL ||
             VTABLE_get_integer(INTERP, info) == VISIT_THAW_CONSTANTS) {
-            pos = &PMC_args(SELF);
+            VISIT_PMC(interp, info, PMC_args(SELF));
         }
         else
-            pos = &INTERP->HLL_info;
+            VISIT_PMC(interp, info, INTERP->HLL_info);
 
-        info->thaw_ptr = pos;
-        (info->visit_pmc_now)(INTERP, *pos, info);
     }
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         if (!PMC_data(SELF)) {
             Parrot_ParrotInterpreter_attributes *attrs =
                 mem_allocate_zeroed_typed(Parrot_ParrotInterpreter_attributes);
@@ -730,7 +727,7 @@
         PMC_interp(SELF) = INTERP;
     }
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         PMC * const new_info = PMC_args(SELF);
         const INTVAL  m      = VTABLE_elements(INTERP, new_info);
         INTVAL  i;
@@ -845,5 +842,3 @@
  * End:
  * vim: expandtab shiftwidth=4:
  */
-
-

Modified: trunk/src/pmc/resizablebooleanarray.pmc
==============================================================================
--- trunk/src/pmc/resizablebooleanarray.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/resizablebooleanarray.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -404,14 +404,14 @@
 
 =over 4
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the string.
 
 =cut
 
 */
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         /* XXX Dino - I'm concerned about freezing the entire
             allocated block of memory, it's dependent on the
             BITS_PER_CHAR value.
@@ -438,14 +438,14 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the string.
 
 =cut
 
 */
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         unsigned char   *bit_array;
         const UINTVAL    head_pos = VTABLE_shift_integer(INTERP, info);
         const UINTVAL    tail_pos = VTABLE_shift_integer(INTERP, info);

Modified: trunk/src/pmc/resizableintegerarray.pmc
==============================================================================
--- trunk/src/pmc/resizableintegerarray.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/resizableintegerarray.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -279,11 +279,11 @@
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the array.
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the array.
 
@@ -291,7 +291,7 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         INTVAL   *int_array;
         INTVAL    i, n, rt;
 
@@ -308,7 +308,7 @@
             VTABLE_push_integer(INTERP, info, int_array[i]);
     }
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         const INTVAL n = VTABLE_shift_integer(INTERP, info);
         const INTVAL rt = VTABLE_shift_integer(INTERP, info);
 

Modified: trunk/src/pmc/scheduler.pmc
==============================================================================
--- trunk/src/pmc/scheduler.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/scheduler.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -277,7 +277,7 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 Visits the contents of the scheduler (used by freeze/thaw).
 
@@ -287,7 +287,7 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         /* 1) visit task list */
         VISIT_PMC_ATTR(INTERP, info, SELF, Scheduler, task_list);
 
@@ -298,7 +298,7 @@
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Archives the scheduler.
 
@@ -306,7 +306,7 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         Parrot_Scheduler_attributes * const core_struct = PARROT_SCHEDULER(SELF);
 
         /* 1) freeze scheduler id */
@@ -319,7 +319,7 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Unarchives the scheduler.
 
@@ -327,7 +327,7 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         /* 1. thaw scheduler id */
         const INTVAL id = VTABLE_shift_integer(INTERP, info);
 
@@ -347,7 +347,7 @@
 
 /*
 
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
 
 Finishes thawing the scheduler.
 
@@ -355,7 +355,7 @@
 
 */
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         Parrot_cx_refresh_task_list(INTERP, SELF);
     }
 

Modified: trunk/src/pmc/schedulermessage.pmc
==============================================================================
--- trunk/src/pmc/schedulermessage.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/schedulermessage.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -206,7 +206,7 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the scheduler message.
 
@@ -216,20 +216,14 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
-        Parrot_SchedulerMessage_attributes * const core_struct =
-            PARROT_SCHEDULERMESSAGE(SELF);
-        PMC **pos;
-
-        /* 1) visit message data */
-        pos            = &core_struct->data;
-        info->thaw_ptr = pos;
-        (info->visit_pmc_now)(INTERP, *pos, info);
+    VTABLE void visit(PMC *info) {
+        /* visit message data */
+        VISIT_PMC(INTERP, info, PARROT_SCHEDULERMESSAGE(SELF)->data);
     }
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the scheduler message.
 
@@ -237,7 +231,7 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         Parrot_SchedulerMessage_attributes * const core_struct =
             PARROT_SCHEDULERMESSAGE(SELF);
 
@@ -250,7 +244,7 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the scheduler message.
 
@@ -258,7 +252,7 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         /* 1. thaw message id */
         const INTVAL id = VTABLE_shift_integer(INTERP, info);
 

Modified: trunk/src/pmc/string.pmc
==============================================================================
--- trunk/src/pmc/string.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/string.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -778,28 +778,28 @@
 
 =over 4
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the string.
 
 =cut
 
 */
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         SUPER(info);
         VTABLE_push_string(INTERP, info, VTABLE_get_string(INTERP, SELF));
     }
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the string.
 
 =cut
 
 */
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         SUPER(info);
         SET_ATTR_str_val(INTERP, SELF, VTABLE_shift_string(INTERP, info));
     }

Modified: trunk/src/pmc/sub.pmc
==============================================================================
--- trunk/src/pmc/sub.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/sub.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -619,11 +619,11 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the sub.
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Archives the subroutine.
 
@@ -631,7 +631,7 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         VISIT_PMC_ATTR(INTERP, info, SELF, Sub, namespace_name);
 
         VISIT_PMC_ATTR(INTERP, info, SELF, Sub, multi_signature);
@@ -651,7 +651,7 @@
         SUPER(info);
     }
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         Parrot_Sub_attributes *sub;
         STRING                *hll_name;
         int i;
@@ -709,7 +709,7 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Unarchives the subroutine.
 
@@ -717,7 +717,7 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         Parrot_Sub_attributes *sub;
         INTVAL flags;
         int    i;

Modified: trunk/src/pmc/task.pmc
==============================================================================
--- trunk/src/pmc/task.pmc	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc/task.pmc	Tue Feb  2 19:38:35 2010	(r43706)
@@ -385,7 +385,7 @@
 
 /*
 
-=item C<void visit(visit_info *info)>
+=item C<void visit(PMC *info)>
 
 This is used by freeze/thaw to visit the contents of the task.
 
@@ -395,14 +395,14 @@
 
 */
 
-    VTABLE void visit(visit_info *info) {
+    VTABLE void visit(PMC *info) {
         /* 1) visit code block */
         VISIT_PMC_ATTR(INTERP, info, SELF, Task, codeblock);
     }
 
 /*
 
-=item C<void freeze(visit_info *info)>
+=item C<void freeze(PMC *info)>
 
 Used to archive the task.
 
@@ -410,7 +410,7 @@
 
 */
 
-    VTABLE void freeze(visit_info *info) {
+    VTABLE void freeze(PMC *info) {
         const Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
 
         /* 1) freeze task id */
@@ -434,7 +434,7 @@
 
 /*
 
-=item C<void thaw(visit_info *info)>
+=item C<void thaw(PMC *info)>
 
 Used to unarchive the task.
 
@@ -442,7 +442,7 @@
 
 */
 
-    VTABLE void thaw(visit_info *info) {
+    VTABLE void thaw(PMC *info) {
         /* 1. thaw task id */
         const INTVAL id = VTABLE_shift_integer(INTERP, info);
 
@@ -486,7 +486,7 @@
 
 /*
 
-=item C<void thawfinish(visit_info *info)>
+=item C<void thawfinish(PMC *info)>
 
 Called after the task has been thawed.
 
@@ -494,7 +494,7 @@
 
 */
 
-    VTABLE void thawfinish(visit_info *info) {
+    VTABLE void thawfinish(PMC *info) {
         Parrot_Task_attributes * core_struct = PARROT_TASK(SELF);
 
         UNUSED(core_struct); /* TODO: Rebuild the task index. */

Modified: trunk/src/pmc_freeze.c
==============================================================================
--- trunk/src/pmc_freeze.c	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/pmc_freeze.c	Tue Feb  2 19:38:35 2010	(r43706)
@@ -18,10 +18,6 @@
 Container PMCs call a "todo-callback" for all contained PMCs. The
 individual action vtable (freeze/thaw) is then called for all todo-PMCs.
 
-In the current implementation C<visit_info> is a stand-in for some kind of
-serializer PMC which will eventually be written. It associates a Parrot
-C<STRING> with a vtable.
-
 =cut
 
 */
@@ -30,745 +26,13 @@
 #include "pmc/pmc_callcontext.h"
 #include "pmc_freeze.str"
 
-/* HEADERIZER HFILE: include/parrot/pmc_freeze.h */
-/* HEADERIZER BEGIN: static */
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-
-static void create_buffer(PARROT_INTERP,
-    ARGIN_NULLOK(PMC *pmc),
-    ARGMOD(visit_info *info))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*info);
-
-PARROT_INLINE
-static void ensure_buffer_size(PARROT_INTERP,
-    ARGIN(visit_info *io),
-    size_t len)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static INTVAL get_visit_integer(PARROT_INTERP, ARGIN(visit_info *io))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_INLINE
-static INTVAL INFO_HAS_DATA(ARGIN(visit_info *io))
-        __attribute__nonnull__(1);
-
-PARROT_INLINE
-static INTVAL OUTPUT_LENGTH(ARGIN(visit_info *io))
-        __attribute__nonnull__(1);
-
-static void push_opcode_integer(PARROT_INTERP,
-    ARGIN(visit_info *io),
-    INTVAL v)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static void push_opcode_number(PARROT_INTERP,
-    ARGIN(visit_info *io),
-    FLOATVAL v)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static void push_opcode_string(PARROT_INTERP,
-    ARGIN(visit_info *io),
-    ARGIN(STRING *v))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
-
-static INTVAL shift_opcode_integer(SHIM_INTERP, ARGIN(visit_info *io))
-        __attribute__nonnull__(2);
-
-static FLOATVAL shift_opcode_number(SHIM_INTERP, ARGIN(visit_info *io))
-        __attribute__nonnull__(2);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING* shift_opcode_string(PARROT_INTERP, ARGIN(visit_info *io))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-static void visit_info_init(PARROT_INTERP,
-    ARGOUT(visit_info *info),
-    visit_enum_type what,
-    ARGIN(STRING *input),
-    ARGIN(PMC *pmc))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(4)
-        __attribute__nonnull__(5)
-        FUNC_MODIFIES(*info);
-
-static void visit_loop_todo_list(PARROT_INTERP,
-    ARGIN_NULLOK(PMC *current),
-    ARGIN(visit_info *info))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3);
-
-static void visit_todo_list_freeze(PARROT_INTERP,
-    ARGIN_NULLOK(PMC* pmc),
-    ARGIN(visit_info* info))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3);
-
-PARROT_INLINE
-static void visit_todo_list_thaw(PARROT_INTERP,
-    SHIM(PMC* pmc_not_used),
-    ARGIN(visit_info* info))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3);
-
-#define ASSERT_ARGS_create_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(info))
-#define ASSERT_ARGS_ensure_buffer_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_get_visit_integer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_INFO_HAS_DATA __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_OUTPUT_LENGTH __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_push_opcode_integer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_push_opcode_number __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_push_opcode_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(io) \
-    , PARROT_ASSERT_ARG(v))
-#define ASSERT_ARGS_shift_opcode_integer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_shift_opcode_number __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_shift_opcode_string __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_visit_info_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(info) \
-    , PARROT_ASSERT_ARG(input) \
-    , PARROT_ASSERT_ARG(pmc))
-#define ASSERT_ARGS_visit_loop_todo_list __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(info))
-#define ASSERT_ARGS_visit_todo_list_freeze __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(info))
-#define ASSERT_ARGS_visit_todo_list_thaw __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(info))
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: static */
-
 /* when thawing a string longer then this size, we first do a GC run and then
  * block GC - the system can't give us more headers */
 
 #define THAW_BLOCK_GC_SIZE 100000
 
-/* preallocate freeze image for aggregates with this estimation */
-#define FREEZE_BYTES_PER_ITEM 9
-
-/* macros/constants to handle packing/unpacking of PMC IDs and flags
- * the 2 LSBs are used for flags, all other bits are used for PMC ID
- */
-#define PackID_new(id, flags)       (((UINTVAL)(id) * 4) | ((UINTVAL)(flags) & 3))
-#define PackID_get_PMCID(id)        ((UINTVAL)(id) / 4)
-#define PackID_set_PMCID(lv, id)    (lv) = PackID_new((id), PackID_get_FLAGS(lv))
-#define PackID_get_FLAGS(id)        ((UINTVAL)(id) & 3)
-#define PackID_set_FLAGS(lv, flags) (lv) = PackID_new(PackID_get_PMCID(lv), (flags))
-
-enum {
-    enum_PackID_normal     = 0,
-    enum_PackID_seen       = 1,
-};
-
-/*
-
-=head2 C<opcode_t> IO Functions
-
-=over 4
-
-=item C<static void ensure_buffer_size(PARROT_INTERP, visit_info *io, size_t
-len)>
-
-Checks the size of the "stream" buffer to see if it can accommodate
-C<len> more bytes. If not, expands the buffer.
-
-=cut
-
-*/
-
-#define GET_VISIT_CURSOR(io) \
-    ((opcode_t *)(((char *)Buffer_bufstart((io)->buffer) + (io)->pos)))
-#define SET_VISIT_CURSOR(io, x) do {\
-    (io)->pos = ((char *)(x) - (char *)Buffer_bufstart((io)->buffer)); \
-} while (0)
-#define INC_VISIT_CURSOR(io, x) do {\
-    (io)->pos += (x); \
-} while (0)
-
-#define BYTECODE_SHIFT_OK(io) PARROT_ASSERT((io)->pos <= (io)->input_length)
-
-
-PARROT_INLINE
-static void
-ensure_buffer_size(PARROT_INTERP, ARGIN(visit_info *io), size_t len)
-{
-    ASSERT_ARGS(ensure_buffer_size)
-    Buffer *buf         = io->buffer;
-    const size_t used   = io->pos;
-    const int need_free = Buffer_buflen(buf) - used - len;
-
-    /* grow by factor 1.5 or such */
-    if (need_free <= 16) {
-        size_t new_size = (size_t) (Buffer_buflen(buf) * 1.5);
-        if (new_size < Buffer_buflen(buf) - need_free + 512)
-            new_size = Buffer_buflen(buf) - need_free + 512;
-        Parrot_gc_reallocate_buffer_storage(interp, buf, new_size);
-
-        PARROT_ASSERT(Buffer_buflen(buf) - used - len >= 15);
-    }
-
-#ifndef DISABLE_GC_DEBUG
-    Parrot_gc_compact_memory_pool(interp);
-#endif
-
-}
-
-/*
-
-=item C<static INTVAL OUTPUT_LENGTH(visit_info *io)>
-
-XXX TODO
-
-=cut
-
-*/
-
-PARROT_INLINE
-static INTVAL
-OUTPUT_LENGTH(ARGIN(visit_info *io)) {
-    ASSERT_ARGS(OUTPUT_LENGTH)
-    return io->pos;
-}
-
-/*
-
-=item C<static INTVAL INFO_HAS_DATA(visit_info *io)>
-
-XXX TODO
-
-=cut
-
-*/
-
-PARROT_INLINE
-static INTVAL
-INFO_HAS_DATA(ARGIN(visit_info *io)) {
-    ASSERT_ARGS(INFO_HAS_DATA)
-    return io->pos < io->input_length;
-}
-
-
-/*
-
-=item C<static INTVAL get_visit_integer(PARROT_INTERP, visit_info *io)>
-
-get the flags describing the visit action
-
-=cut
-
-*/
-
-static INTVAL
-get_visit_integer(PARROT_INTERP, ARGIN(visit_info *io)) {
-    ASSERT_ARGS(get_visit_integer)
-    return io->what;
-}
-
-/*
-
-=item C<static void push_opcode_integer(PARROT_INTERP, visit_info *io, INTVAL
-v)>
-
-Pushes the integer C<v> onto the end of the C<*io> "stream".
-
-XXX assumes sizeof (opcode_t) == sizeof (INTVAL).
-
-=cut
-
-*/
-
-static void
-push_opcode_integer(PARROT_INTERP, ARGIN(visit_info *io), INTVAL v)
-{
-    ASSERT_ARGS(push_opcode_integer)
-    size_t len = PF_size_integer() * sizeof (opcode_t);
-    ensure_buffer_size(interp, io, len);
-    SET_VISIT_CURSOR(io, PF_store_integer(GET_VISIT_CURSOR(io), v));
-}
-
-
-/*
-
-=item C<static void push_opcode_number(PARROT_INTERP, visit_info *io, FLOATVAL
-v)>
-
-Pushes the number C<v> onto the end of the C<*io> "stream".
-
-=cut
-
-*/
-
-static void
-push_opcode_number(PARROT_INTERP, ARGIN(visit_info *io), FLOATVAL v)
-{
-    ASSERT_ARGS(push_opcode_number)
-    size_t len = PF_size_number() * sizeof (opcode_t);
-    ensure_buffer_size(interp, io, len);
-    SET_VISIT_CURSOR(io, PF_store_number(GET_VISIT_CURSOR(io), &v));
-}
-
-
-/*
-
-=item C<static void push_opcode_string(PARROT_INTERP, visit_info *io, STRING
-*v)>
-
-Pushes the string C<*v> onto the end of the C<*io> "stream".
-
-=cut
-
-*/
-
-static void
-push_opcode_string(PARROT_INTERP, ARGIN(visit_info *io), ARGIN(STRING *v))
-{
-    ASSERT_ARGS(push_opcode_string)
-    size_t len = PF_size_string(v) * sizeof (opcode_t);
-    ensure_buffer_size(interp, io, len);
-    SET_VISIT_CURSOR(io, PF_store_string(GET_VISIT_CURSOR(io), v));
-}
-
-/*
-
-=item C<static void push_opcode_pmc(PARROT_INTERP, visit_info *io, PMC *v)>
-
-Pushes a reference to pmc C<*v> onto the end of the C<*io> "stream". If C<*v>
-hasn't been seen yet, it is also pushed onto the todo list.
-
-=cut
-
-*/
-
-static void
-push_opcode_pmc(PARROT_INTERP, ARGIN(visit_info *io), ARGIN(PMC *v)) {
-    io->thaw_ptr = &v;
-    (io->visit_pmc_now)(interp, v, io);
-}
-
-/*
-
-=item C<static INTVAL shift_opcode_integer(PARROT_INTERP, visit_info *io)>
-
-Removes and returns an integer from the start of the C<*io> "stream".
-
-=cut
-
-*/
-
-static INTVAL
-shift_opcode_integer(SHIM_INTERP, ARGIN(visit_info *io))
-{
-    ASSERT_ARGS(shift_opcode_integer)
-    opcode_t *pos  = GET_VISIT_CURSOR(io);
-    const INTVAL i = PF_fetch_integer(io->pf, (const opcode_t **)&pos);
-    SET_VISIT_CURSOR(io, pos);
-    BYTECODE_SHIFT_OK(io);
-    return i;
-}
-
-
-/*
-
-=item C<static FLOATVAL shift_opcode_number(PARROT_INTERP, visit_info *io)>
-
-Removes and returns an number from the start of the C<*io> "stream".
-
-=cut
-
-*/
-
-static FLOATVAL
-shift_opcode_number(SHIM_INTERP, ARGIN(visit_info *io))
-{
-    ASSERT_ARGS(shift_opcode_number)
-    opcode_t *pos     = GET_VISIT_CURSOR(io);
-    const FLOATVAL f  = PF_fetch_number(io->pf, (const opcode_t **)&pos);
-    SET_VISIT_CURSOR(io, pos);
-    BYTECODE_SHIFT_OK(io);
-    return f;
-}
-
-
-/*
-
-=item C<static STRING* shift_opcode_string(PARROT_INTERP, visit_info *io)>
-
-Removes and returns a string from the start of the C<*io> "stream".
-
-=cut
-
-*/
-
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static STRING*
-shift_opcode_string(PARROT_INTERP, ARGIN(visit_info *io))
-{
-    ASSERT_ARGS(shift_opcode_string)
-    opcode_t *pos    = GET_VISIT_CURSOR(io);
-    STRING * const s = PF_fetch_string(interp, io->pf, (const opcode_t **)&pos);
-    SET_VISIT_CURSOR(io, pos);
-    BYTECODE_SHIFT_OK(io);
-    return s;
-}
-
-/*
-
-=item C<static PMC *shift_opcode_pmc(PARROT_INTERP, visit_info *io)>
-
-Removes and returns a reference to a pmc from the start of the C<*io> "stream".
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CANNOT_RETURN_NULL
-static PMC *
-shift_opcode_pmc(PARROT_INTERP, ARGIN(visit_info *io)) {
-    PMC *result;
-    io->thaw_ptr = &result;
-    (io->visit_pmc_now)(interp, NULL, io);
-    return result;
-}
-
-/*
-
-=back
-
-=head2 Helper Functions
-
-=over 4
-
-=cut
-
-*/
-
-/*
- * this function setup stuff may be replaced by a real PMC
- * in the future
- * TODO add read/write header functions, e.g. vtable->init_pmc
- */
-
-static image_funcs opcode_funcs = {
-    get_visit_integer,
-    push_opcode_integer,
-    push_opcode_string,
-    push_opcode_number,
-    push_opcode_pmc,
-    shift_opcode_integer,
-    shift_opcode_string,
-    shift_opcode_number,
-    shift_opcode_pmc
-};
-
-/*
-
-=item C<static void visit_info_init(PARROT_INTERP, visit_info *info,
-visit_enum_type what, STRING *input, PMC *pmc)>
-
-Initializes the C<*info> lists.
-
-=cut
-
-*/
-#define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
-
-static void
-visit_info_init(PARROT_INTERP, ARGOUT(visit_info *info),
-  visit_enum_type what, ARGIN(STRING *input), ARGIN(PMC *pmc))
-{
-    ASSERT_ARGS(visit_info_init)
-    /* We want to store a 16-byte aligned header, but the actual * header may be shorter. */
-    const unsigned int header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
-
-    PackFile *pf = info->pf = PackFile_new(interp, 0);
-    info->what = what;
-    info->vtable = &opcode_funcs;
-    info->image_io = info; /* backwards-compat hack */
-
-    if (info->what == VISIT_FREEZE_NORMAL) {
-        info->visit_pmc_now  = visit_todo_list_freeze;
-        create_buffer(interp, pmc, info);
-        ensure_buffer_size(interp, info, header_length);
-        mem_sys_memcopy(GET_VISIT_CURSOR(info), pf->header, PACKFILE_HEADER_BYTES);
-        INC_VISIT_CURSOR(info, header_length);
-    }
-    else { /* VISIT_THAW_ */
-        int unpacked_length;
-        info->visit_pmc_now    = visit_todo_list_thaw;
-        info->buffer = (Buffer *)input;
-        PARROT_ASSERT(input->_bufstart == input->strstart);
-        SET_VISIT_CURSOR(info, Buffer_bufstart(info->buffer));
-        info->input_length = input->strlen;
-
-        pf->options |= PFOPT_PMC_FREEZE_ONLY;
-        unpacked_length = PackFile_unpack(interp, pf, GET_VISIT_CURSOR(info), info->input_length);
-        if (!unpacked_length) {
-            PackFile_destroy(interp, info->pf);
-            Parrot_ex_throw_from_c_args(interp, NULL,
-                    EXCEPTION_INVALID_STRING_REPRESENTATION,
-                    "PackFile header failed during unpack");
-        }
-        else {
-            INC_VISIT_CURSOR(info, header_length);
-        }
-    }
-
-    /* we must use PMCs here so that they get marked properly */
-    info->todo        = pmc_new(interp, enum_class_ResizablePMCArray);
-    if (info->what == VISIT_FREEZE_NORMAL) {
-        info->seen    = pmc_new(interp, enum_class_Hash);
-        VTABLE_set_pointer(interp, info->seen, parrot_new_intval_hash(interp));
-        info->id_list = PMCNULL;
-    }
-    else {
-        info->seen    = PMCNULL;
-        info->id_list = pmc_new(interp, enum_class_ResizablePMCArray);
-    }
-    info->id          = 0;
-    info->extra_flags = EXTRA_IS_NULL;
-
-    visit_loop_todo_list(interp, pmc, info);
-    PackFile_destroy(interp, info->pf);
-}
-
-
-PARROT_INLINE
-static PMC*
-id_list_get(PARROT_INTERP, ARGIN(visit_info *info), UINTVAL id) {
-    PMC *pos = VTABLE_get_pmc_keyed_int(interp, info->id_list, id);
-
-    if (pos && pos != ((void *)-1))
-        return pos;
-    return NULL;
-}
-
 /*
 
-=item C<static void visit_todo_list_thaw(PARROT_INTERP, PMC* pmc_not_used,
-visit_info* info)>
-
-Callback for thaw - action first.
-thaws and return a PMC.
-
-=cut
-
-*/
-
-PARROT_INLINE
-static void
-visit_todo_list_thaw(PARROT_INTERP, SHIM(PMC* pmc_not_used), ARGIN(visit_info* info))
-{
-    ASSERT_ARGS(visit_todo_list_thaw)
-
-    UINTVAL  n            = VTABLE_shift_integer(interp, info);
-    UINTVAL  id           = PackID_get_PMCID(n);
-    int      packid_flags = PackID_get_FLAGS(n);
-    PMC     *pmc          = PMCNULL;
-
-    PARROT_ASSERT(info->what == VISIT_THAW_NORMAL);
-
-    switch (packid_flags) {
-      case enum_PackID_seen:
-        if (id) /* got a non-NULL PMC */
-            pmc = id_list_get(interp, info, id);
-        break;
-      case enum_PackID_normal:
-        {
-            INTVAL type = VTABLE_shift_integer(interp, info);
-            if (type <= 0 || type > interp->n_vtable_max)
-                Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown PMC type to thaw %d", type);
-
-            pmc = pmc_new_noinit(interp, type);
-            VTABLE_thaw(interp, pmc, info);
-
-            VTABLE_set_pmc_keyed_int(interp, info->id_list, id, pmc);
-            /* remember nested aggregates depth first */
-            VTABLE_unshift_pmc(interp, info->todo, pmc);
-        }
-        break;
-      default:
-        Parrot_ex_throw_from_c_args(interp, NULL, 1, "Unknown PMC id args thaw %d", packid_flags);
-        break;
-    }
-
-    *info->thaw_ptr = pmc;
-}
-
-
-/*
-
-=item C<static void visit_todo_list_freeze(PARROT_INTERP, PMC* pmc, visit_info*
-info)>
-
-Checks the seen PMC via the todo list.
-
-=cut
-
-*/
-
-static void
-visit_todo_list_freeze(PARROT_INTERP, ARGIN_NULLOK(PMC* pmc), ARGIN(visit_info* info))
-{
-    ASSERT_ARGS(visit_todo_list_freeze)
-    UINTVAL id;
-    int packid_type;
-
-    PARROT_ASSERT(info->what == VISIT_FREEZE_NORMAL);
-
-    if (PMC_IS_NULL(pmc)) {
-        id   = 0;
-        packid_type = enum_PackID_seen;
-    }
-    else {
-        Hash *hash = (Hash *)VTABLE_get_pointer(interp, info->seen);
-        HashBucket * const b = parrot_hash_get_bucket(interp, hash, pmc);
-        if (b) {
-            id = (UINTVAL) b->value;
-            packid_type = enum_PackID_seen;
-        }
-        else {
-            info->id++; /* next id to freeze */
-            id = info->id;
-            packid_type = enum_PackID_normal;
-        }
-    }
-
-    VTABLE_push_integer(interp, info, PackID_new(id, packid_type));
-
-    if (packid_type == enum_PackID_normal) {
-        Hash *hash = (Hash *)VTABLE_get_pointer(interp, info->seen);
-        PARROT_ASSERT(pmc);
-        VTABLE_push_integer(interp, info,
-                PObj_is_object_TEST(pmc) ? enum_class_Object : pmc->vtable->base_type);
-        parrot_hash_put(interp, hash, pmc, (void *)id);
-        VTABLE_unshift_pmc(interp, info->todo, pmc);
-        VTABLE_freeze(interp, pmc, info);
-    }
-}
-
-
-/*
-
-=item C<static void visit_loop_todo_list(PARROT_INTERP, PMC *current, visit_info
-*info)>
-
-The thaw loop.
-
-=cut
-
-*/
-
-static void
-visit_loop_todo_list(PARROT_INTERP, ARGIN_NULLOK(PMC *current),
-        ARGIN(visit_info *info))
-{
-    ASSERT_ARGS(visit_loop_todo_list)
-    const int  thawing = (info->what == VISIT_THAW_NORMAL);
-    PMC * const todolist = info->todo;
-
-    (info->visit_pmc_now)(interp, current, info);
-
-    /* can't cache upper limit, visit may append items */
-    while (VTABLE_elements(interp, todolist)) {
-        current = VTABLE_shift_pmc(interp, todolist);
-        if (!current)
-            Parrot_ex_throw_from_c_args(interp, NULL, 1,
-                    "NULL current PMC in visit_loop_todo_list");
-
-        PARROT_ASSERT(current->vtable);
-        VTABLE_visit(interp, current, info);
-        VISIT_PMC(interp, info, PMC_metadata(current));
-    }
-
-    if (thawing)
-        /* we're done reading the image */
-        PARROT_ASSERT(!INFO_HAS_DATA(info));
-
-    if (thawing) {
-        /* on thawing call thawfinish for each processed PMC */
-        const INTVAL n           = VTABLE_elements(interp, info->id_list);
-        int          i;
-
-        /* Thaw in reverse order. We have to fully thaw younger PMCs before use them in older */
-        for (i = n-1; i >= 0; --i) {
-            current = VTABLE_get_pmc_keyed_int(interp, info->id_list, i);
-            if (!PMC_IS_NULL(current))
-                VTABLE_thawfinish(interp, current, info);
-        }
-    }
-}
-
-
-/*
-
-=item C<static void create_buffer(PARROT_INTERP, PMC *pmc, visit_info *info)>
-
-Allocate buffer to some estimated size.
-
-=cut
-
-*/
-
-static void
-create_buffer(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), ARGMOD(visit_info *info))
-{
-    ASSERT_ARGS(create_buffer)
-    STRING *array = CONST_STRING(interp, "array");
-    STRING *hash  = CONST_STRING(interp, "hash");
-    INTVAL  len;
-
-    if (!PMC_IS_NULL(pmc)
-    && (VTABLE_does(interp, pmc, array) || VTABLE_does(interp, pmc, hash))) {
-        const INTVAL items = VTABLE_elements(interp, pmc);
-        /* TODO check e.g. first item of aggregate and estimate size */
-        len = (items ? items : 1) * FREEZE_BYTES_PER_ITEM;
-    }
-    else
-        len = FREEZE_BYTES_PER_ITEM;
-
-    info->buffer = (Buffer *)Parrot_gc_new_bufferlike_header(interp, sizeof (Buffer));
-    Parrot_gc_allocate_buffer_storage_aligned(interp, info->buffer, len);
-    SET_VISIT_CURSOR(info, Buffer_bufstart(info->buffer));
-}
-
-
-/*
-
-=back
-
 =head2 Public Interface
 
 =over 4
@@ -788,10 +52,9 @@
 Parrot_freeze(PARROT_INTERP, ARGIN(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_freeze)
-    visit_info info;
-
-    visit_info_init(interp, &info, VISIT_FREEZE_NORMAL, STRINGNULL, pmc);
-    return Parrot_str_new_from_buffer(interp, info.buffer, OUTPUT_LENGTH(&info));
+    PMC *image = pmc_new(interp, enum_class_ImageIO);
+    VTABLE_set_pmc(interp, image, pmc);
+    return VTABLE_get_string(interp, image);
 }
 
 
@@ -819,7 +82,7 @@
 {
     ASSERT_ARGS(Parrot_thaw)
 
-    visit_info  info;
+    PMC        *info     = pmc_new(interp, enum_class_ImageIO);
     int         gc_block = 0;
     PMC        *result;
 
@@ -840,9 +103,8 @@
         gc_block = 1;
     }
 
-    info.thaw_ptr = &result;
-    visit_info_init(interp, &info, VISIT_THAW_NORMAL, image, PMCNULL);
-    BYTECODE_SHIFT_OK(&info);
+    VTABLE_set_pointer(interp, info, &result);
+    VTABLE_set_string_native(interp, info, image);
 
     if (gc_block) {
         Parrot_unblock_GC_mark(interp);

Modified: trunk/src/vtable.tbl
==============================================================================
--- trunk/src/vtable.tbl	Tue Feb  2 19:32:37 2010	(r43705)
+++ trunk/src/vtable.tbl	Tue Feb  2 19:38:35 2010	(r43706)
@@ -348,10 +348,10 @@
 PMC* inspect()
 PMC* inspect_str(STRING* what)
 
-void freeze(visit_info* info)
-void thaw  (visit_info* info) :write
-void thawfinish (visit_info* info) :write
-void visit (visit_info* info)
+void freeze(PMC* info)
+void thaw  (PMC* info) :write
+void thawfinish (PMC* info) :write
+void visit (PMC* info)
 
 void share()
 

Modified: trunk/t/native_pbc/annotations.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/integer_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/number_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: trunk/t/native_pbc/string_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.


More information about the parrot-commits mailing list