[svn:parrot] r49130 - in trunk: . src src/pmc t/pmc

plobsing at svn.parrot.org plobsing at svn.parrot.org
Sat Sep 18 03:47:35 UTC 2010


Author: plobsing
Date: Sat Sep 18 03:47:34 2010
New Revision: 49130
URL: https://trac.parrot.org/parrot/changeset/49130

Log:
convert remaining imageio functionality to ImageIOFreeze for symmetry

Added:
   trunk/src/pmc/imageiofreeze.pmc
Deleted:
   trunk/src/pmc/imageio.pmc
Modified:
   trunk/MANIFEST
   trunk/src/pmc_freeze.c
   trunk/t/pmc/imageio.t

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Sat Sep 18 03:22:55 2010	(r49129)
+++ trunk/MANIFEST	Sat Sep 18 03:47:34 2010	(r49130)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Sat Sep 18 00:46:33 2010 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Sat Sep 18 03:19:23 2010 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -1379,7 +1379,7 @@
 src/pmc/hash.pmc                                            []
 src/pmc/hashiterator.pmc                                    []
 src/pmc/hashiteratorkey.pmc                                 []
-src/pmc/imageio.pmc                                         []
+src/pmc/imageiofreeze.pmc                                   []
 src/pmc/imageiosize.pmc                                     []
 src/pmc/imageiostrings.pmc                                  []
 src/pmc/imageiothaw.pmc                                     []

Deleted: trunk/src/pmc/imageio.pmc
==============================================================================
--- trunk/src/pmc/imageio.pmc	Sat Sep 18 03:47:34 2010	(r49129)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,776 +0,0 @@
-/*
-Copyright (C) 2010, Parrot Foundation.
-$Id$
-
-=head1 NAME
-
-src/pmc/imageio.pmc - ImageIO PMC
-
-=head1 DESCRIPTION
-
-Freezes and thaws other PMCs.
-
-=head1 FUNCTIONS
-
-=over 4
-
-=cut
-
-*/
-
-#include "parrot/imageio.h"
-
-/* HEADERIZER HFILE: none */
-/* 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(PMC *info))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(3)
-        FUNC_MODIFIES(*info);
-
-PARROT_INLINE
-static void ensure_buffer_size(PARROT_INTERP, ARGIN(PMC *io), size_t len)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_INLINE
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-static opcode_t * GET_VISIT_CURSOR(ARGIN(const PMC *pmc))
-        __attribute__nonnull__(1);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-PARROT_INLINE
-static PMC* id_list_get(PARROT_INTERP, ARGIN(const PMC *io), UINTVAL id)
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_INLINE
-static void INC_VISIT_CURSOR(ARGMOD(PMC *pmc), UINTVAL inc)
-        __attribute__nonnull__(1)
-        FUNC_MODIFIES(*pmc);
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_INLINE
-static INTVAL INFO_HAS_DATA(ARGIN(const PMC *io))
-        __attribute__nonnull__(1);
-
-PARROT_INLINE
-static void SET_VISIT_CURSOR(ARGMOD(PMC *pmc), ARGIN(const char *cursor))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*pmc);
-
-#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_CURSOR __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(pmc))
-#define ASSERT_ARGS_id_list_get __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_INC_VISIT_CURSOR __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(pmc))
-#define ASSERT_ARGS_INFO_HAS_DATA __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(io))
-#define ASSERT_ARGS_SET_VISIT_CURSOR __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(pmc) \
-    , PARROT_ASSERT_ARG(cursor))
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
-/* HEADERIZER END: static */
-
-/*
-
-=item C<static opcode_t * GET_VISIT_CURSOR(const PMC *pmc)>
-
-=cut
-
-*/
-
-PARROT_INLINE
-PARROT_CANNOT_RETURN_NULL
-PARROT_WARN_UNUSED_RESULT
-static opcode_t *
-GET_VISIT_CURSOR(ARGIN(const PMC *pmc))
-{
-    ASSERT_ARGS(GET_VISIT_CURSOR)
-
-    char * const buf = (char *)Buffer_bufstart(PARROT_IMAGEIO(pmc)->buffer);
-    const size_t pos = PARROT_IMAGEIO(pmc)->pos;
-    return (opcode_t *)(buf + pos);
-}
-
-/*
-
-=item C<static void SET_VISIT_CURSOR(PMC *pmc, const char *cursor)>
-
-=cut
-
-*/
-
-
-PARROT_INLINE
-static void
-SET_VISIT_CURSOR(ARGMOD(PMC *pmc), ARGIN(const char *cursor))
-{
-    ASSERT_ARGS(SET_VISIT_CURSOR)
-
-    const char * const bufstart  = (const char *)Buffer_bufstart(PARROT_IMAGEIO(pmc)->buffer);
-    PARROT_IMAGEIO(pmc)->pos = (cursor - bufstart);
-}
-
-/*
-
-=item C<static void INC_VISIT_CURSOR(PMC *pmc, UINTVAL inc)>
-
-=cut
-
-*/
-
-
-PARROT_INLINE
-static void
-INC_VISIT_CURSOR(ARGMOD(PMC *pmc), UINTVAL inc)
-{
-    ASSERT_ARGS(INC_VISIT_CURSOR)
-
-    PARROT_IMAGEIO(pmc)->pos += inc;
-}
-
-
-#define BYTECODE_SHIFT_OK(pmc) PARROT_ASSERT( \
-    PARROT_IMAGEIO(pmc)->pos <= PARROT_IMAGEIO(pmc)->input_length)
-
-/*
-
-=item C<static void create_buffer(PARROT_INTERP, PMC *pmc, PMC *info)>
-
-=cut
-
-*/
-
-static void
-create_buffer(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), ARGMOD(PMC *info))
-{
-    ASSERT_ARGS(create_buffer)
-
-    INTVAL  len;
-
-    if (!PMC_IS_NULL(pmc)) {
-        STRING * const array = CONST_STRING(interp, "array");
-        STRING * const 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 =
-        Parrot_gc_new_bufferlike_header(interp, sizeof (Buffer));
-    Parrot_gc_allocate_buffer_storage_aligned(interp,
-        PARROT_IMAGEIO(info)->buffer, len);
-    SET_VISIT_CURSOR(info,
-        (const char *)Buffer_bufstart(PARROT_IMAGEIO(info)->buffer));
-}
-
-/*
-
-=item C<static void ensure_buffer_size(PARROT_INTERP, PMC *io, size_t len)>
-
-Checks the size of the buffer to see if it can accommodate C<len> more
-bytes. If not, expands the buffer.
-
-=cut
-
-*/
-
-PARROT_INLINE
-static void
-ensure_buffer_size(PARROT_INTERP, ARGIN(PMC *io), size_t len)
-{
-    ASSERT_ARGS(ensure_buffer_size)
-
-    Buffer * const 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
-}
-
-/*
-
-=item C<static INTVAL INFO_HAS_DATA(const PMC *io)>
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_INLINE
-static INTVAL
-INFO_HAS_DATA(ARGIN(const PMC *io))
-{
-    ASSERT_ARGS(INFO_HAS_DATA)
-
-    return PARROT_IMAGEIO(io)->pos < PARROT_IMAGEIO(io)->input_length;
-}
-
-/*
-
-=item C<static PMC* id_list_get(PARROT_INTERP, const PMC *io, UINTVAL id)>
-
-=cut
-
-*/
-
-PARROT_WARN_UNUSED_RESULT
-PARROT_CAN_RETURN_NULL
-PARROT_INLINE
-static PMC*
-id_list_get(PARROT_INTERP, ARGIN(const PMC *io), UINTVAL id)
-{
-    ASSERT_ARGS(id_list_get)
-
-    return VTABLE_get_pmc_keyed_int(interp, PARROT_IMAGEIO(io)->todo, id - 1);
-}
-
-pmclass ImageIO auto_attrs {
-    ATTR Buffer              *buffer;      /* buffer to store the image */
-    ATTR size_t               pos;         /* current read/write buf position */
-    ATTR size_t               input_length;
-    ATTR INTVAL               what;
-    ATTR PMC                 *seen;        /* seen hash */
-    ATTR PMC                 *todo;        /* todo list */
-    ATTR UINTVAL              id;          /* freze ID of PMC */
-    ATTR struct PackFile     *pf;
-    ATTR PackFile_ConstTable *pf_ct;
-
-/*
-
-=back
-
-=head1 VTABLES
-
-=over 4
-
-=cut
-
-*/
-
-/*
-
-=item C<void init()>
-
-Initializes the PMC.
-
-=cut
-
-*/
-    VTABLE void init() {
-        PARROT_IMAGEIO(SELF)->seen = PMCNULL;
-        PARROT_IMAGEIO(SELF)->todo =
-            Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
-
-        PObj_flag_CLEAR(private1, SELF);
-
-        PObj_custom_mark_SET(SELF);
-    }
-
-
-/*
-
-=item C<void destroy()>
-
-Destroys the PMC.
-
-=cut
-
-*/
-    VTABLE void destroy() {
-        PackFile_destroy(INTERP, PARROT_IMAGEIO(SELF)->pf);
-        PARROT_IMAGEIO(SELF)->pf = NULL;
-    }
-
-
-/*
-
-=item C<void mark()>
-
-Marks the PMC as alive.
-
-=cut
-
-*/
-    VTABLE void mark() {
-        PObj * const buffer = (PObj *)(PARROT_IMAGEIO(SELF)->buffer);
-        if (buffer)
-            Parrot_gc_mark_PObj_alive(INTERP, buffer);
-        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->todo);
-        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIO(SELF)->seen);
-    }
-
-
-/*
-
-=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 PMC *get_pmc()>
-
-Gets the result PMC after a thaw.
-
-=cut
-
-*/
-
-    VTABLE PMC *get_pmc() {
-        return VTABLE_get_pmc_keyed_int(INTERP,
-            (PARROT_IMAGEIO(SELF))->todo, 0);
-    }
-
-
-/*
-
-=item C<VTABLE PMC *get_iter()>
-
-Get the C<todo> list for this freeze/thaw for iterating over.
-
-=cut
-
-*/
-
-    VTABLE PMC *get_iter() {
-        return PARROT_IMAGEIO(SELF)->todo;
-    }
-
-/*
-
-=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) {
-        const size_t len = PF_size_integer() * sizeof (opcode_t);
-        ensure_buffer_size(INTERP, SELF, len);
-        SET_VISIT_CURSOR(SELF,
-            (const 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) {
-        const size_t len = PF_size_number() * sizeof (opcode_t);
-        ensure_buffer_size(INTERP, SELF, len);
-        SET_VISIT_CURSOR(SELF,
-            (const 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) {
-        if (PObj_flag_TEST(private1, SELF)) {
-            /* store a reference to constant table entry of string */
-            PMC                 * const v_pmc = key_new_string(interp, v);
-            PackFile_ConstTable * const table = PARROT_IMAGEIO(SELF)->pf_ct;
-            const int idx =
-                PackFile_ConstTable_rlookup(INTERP, table, v_pmc, PFC_STRING);
-
-            if (idx >= 0) {
-                STATICSELF.push_integer(idx);
-                return;
-            }
-
-            /* XXX handle cases where the PMC has changed after
-             * Parrot_freeze_strings was called eg: :immediate subs */
-            STATICSELF.push_integer(-1);
-
-            /* TODO
-             * should really be:
-             * PANIC(INTERP, "string not previously in constant table "
-             *               "when freezing to packfile"); */
-        }
-
-        {
-            const size_t len = PF_size_string(v) * sizeof (opcode_t);
-            ensure_buffer_size(INTERP, SELF, len);
-            SET_VISIT_CURSOR(SELF,
-                (const 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) {
-        UINTVAL id;
-        int packid_type;
-
-        PARROT_ASSERT(PARROT_IMAGEIO(SELF)->what == VISIT_FREEZE_NORMAL);
-
-        if (PMC_IS_NULL(v)) {
-            id   = 0;
-            packid_type = enum_PackID_seen;
-        }
-        else {
-            Hash * const hash = (Hash *)VTABLE_get_pointer(INTERP,
-                    PARROT_IMAGEIO(SELF)->seen);
-            HashBucket * const b = parrot_hash_get_bucket(INTERP, hash, v);
-
-            if (b) {
-                id = (UINTVAL)b->value;
-                packid_type = enum_PackID_seen;
-            }
-            else {
-                ++PARROT_IMAGEIO(SELF)->id; /* next id to freeze */
-                id = PARROT_IMAGEIO(SELF)->id;
-                packid_type = enum_PackID_normal;
-            }
-        }
-
-        SELF.push_integer(PackID_new(id, packid_type));
-
-        if (packid_type == enum_PackID_normal) {
-            Hash * const hash = (Hash *)VTABLE_get_pointer(INTERP,
-                    PARROT_IMAGEIO(SELF)->seen);
-
-            PARROT_ASSERT(v);
-
-            /* workaround to keep ParrotInterpreter PBC hack working */
-            if (v->vtable->base_type == enum_class_ParrotInterpreter)
-                PObj_flag_CLEAR(private1, SELF);
-
-            SELF.push_integer(
-                    PObj_is_object_TEST(v)
-                    ? (INTVAL) enum_class_Object
-                    : v->vtable->base_type);
-
-            parrot_hash_put(INTERP, hash, v, (void *)id);
-            VTABLE_push_pmc(INTERP, PARROT_IMAGEIO(SELF)->todo, v);
-        }
-    }
-
-
-/*
-
-=item C<void set_pointer(void *value)>
-
-Sets the constant table of this ImageIO PMC.
-
-=cut
-
-*/
-
-    VTABLE void set_pointer(void *value) {
-        PObj_flag_SET(private1, SELF);
-        PARROT_IMAGEIO(SELF)->pf_ct = (PackFile_ConstTable *)value;
-    }
-
-
-/*
-
-=item C<VTABLE INTVAL shift_integer()>
-
-Removes and returns an integer from the start of the image.
-
-=cut
-
-*/
-
-    VTABLE INTVAL shift_integer() {
-        /* inlining PF_fetch_integer speeds up PBC thawing measurably */
-        const PackFile      *pf     = PARROT_IMAGEIO(SELF)->pf;
-        const opcode_t      *pos    = GET_VISIT_CURSOR(SELF);
-        const unsigned char *stream = (const unsigned char *)pos;
-        const INTVAL         i      = pf->fetch_iv(stream);
-
-        SET_VISIT_CURSOR(SELF, (const char *)pos + pf->header->wordsize);
-        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() {
-        const opcode_t *pos = GET_VISIT_CURSOR(SELF);
-        FLOATVAL        f   = PF_fetch_number(PARROT_IMAGEIO(SELF)->pf, &pos);
-        SET_VISIT_CURSOR(SELF, (const 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() {
-        if (PObj_flag_TEST(private1, SELF)) {
-            const INTVAL i = STATICSELF.shift_integer();
-
-            if (i >= 0) {
-                PackFile_ConstTable *table = PARROT_IMAGEIO(SELF)->pf_ct;
-
-                if (!table->constants[i].type)
-                    Parrot_ex_throw_from_c_args(interp, NULL,
-                            EXCEPTION_MALFORMED_PACKFILE,
-                            "Reference to constant not yet unpacked %d", i);
-                return table->constants[i].u.string;
-            }
-
-            /* XXX
-             * only got here because constant table doesn't contain the string
-             * fallback on inline strings
-             */
-        }
-
-        {
-            const opcode_t * pos     = GET_VISIT_CURSOR(SELF);
-            STRING         * const s = PF_fetch_string(INTERP,
-                                    PARROT_IMAGEIO(SELF)->pf, &pos);
-            SET_VISIT_CURSOR(SELF, (const 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() {
-        const UINTVAL  n            = SELF.shift_integer();
-        const INTVAL   id           = PackID_get_PMCID(n);
-        const int      packid_flags = PackID_get_FLAGS(n);
-        PMC           *pmc          = PMCNULL;
-
-        PARROT_ASSERT(PARROT_IMAGEIO(SELF)->what == VISIT_THAW_NORMAL);
-
-        switch (packid_flags) {
-            case enum_PackID_seen:
-                if (id) /* got a non-NULL PMC */
-                    pmc = id_list_get(INTERP, SELF, id);
-                break;
-            case enum_PackID_normal:
-                {
-                    PMC * const  todo = PARROT_IMAGEIO(SELF)->todo;
-                    const INTVAL type = VTABLE_shift_integer(INTERP, SELF);
-
-                    PARROT_ASSERT(id - 1
-                            == VTABLE_elements(INTERP, PARROT_IMAGEIO(SELF)->todo));
-
-                    if (type <= 0 || type > INTERP->n_vtable_max)
-                        Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
-                                "Unknown PMC type to thaw %d", type);
-
-                    /* workaround to keep ParrotInterpreter PBC hack working */
-                    if (type == enum_class_ParrotInterpreter)
-                        PObj_flag_CLEAR(private1, SELF);
-
-                    pmc = Parrot_pmc_new_noinit(INTERP, type);
-
-                    VTABLE_set_pmc_keyed_int(INTERP, todo, id - 1, pmc);
-                }
-                break;
-            default:
-                Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
-                        "Unknown PMC id args thaw %d", packid_flags);
-                break;
-        }
-
-        return pmc;
-    }
-
-    VTABLE void set_pmc(PMC *p)
-    {
-        PARROT_IMAGEIO(SELF)->what  = VISIT_FREEZE_NORMAL;
-
-        create_buffer(INTERP, p, SELF);
-        if (PObj_flag_TEST(private1, SELF)) {
-            PARROT_IMAGEIO(SELF)->pf = PARROT_IMAGEIO(SELF)->pf_ct->base.pf;
-        }
-        else {
-            const UINTVAL header_length =
-                GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
-
-            PARROT_IMAGEIO(SELF)->pf = PackFile_new(INTERP, 0);
-            PObj_custom_destroy_SET(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 = Parrot_pmc_new(INTERP, enum_class_Hash);
-        VTABLE_set_pointer(INTERP, PARROT_IMAGEIO(SELF)->seen,
-            parrot_new_intval_hash(INTERP));
-
-        STATICSELF.push_pmc(p);
-        Parrot_visit_loop_visit(INTERP, SELF);
-    }
-
-    VTABLE void set_string_native(STRING *image) {
-        PMC          *unused;
-        PARROT_IMAGEIO(SELF)->what   = VISIT_THAW_NORMAL;
-        PARROT_IMAGEIO(SELF)->buffer = (Buffer *)image;
-
-        PARROT_ASSERT(image->_bufstart == image->strstart);
-
-        SET_VISIT_CURSOR(SELF,
-            (const char *)Buffer_bufstart(PARROT_IMAGEIO(SELF)->buffer));
-        PARROT_IMAGEIO(SELF)->input_length = image->strlen;
-
-        if (PObj_flag_TEST(private1, SELF)) {
-            PARROT_IMAGEIO(SELF)->pf = PARROT_IMAGEIO(SELF)->pf_ct->base.pf;
-        }
-        else {
-            const UINTVAL header_length =
-                 GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
-            int unpacked_length;
-
-            PARROT_IMAGEIO(SELF)->pf   = PackFile_new(INTERP, 0);
-            PObj_custom_destroy_SET(SELF);
-
-            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)
-                INC_VISIT_CURSOR(SELF, header_length);
-            else
-                Parrot_ex_throw_from_c_args(INTERP, NULL,
-                        EXCEPTION_INVALID_STRING_REPRESENTATION,
-                        "PackFile header failed during unpack");
-        }
-
-        unused = STATICSELF.shift_pmc();
-        Parrot_visit_loop_visit(INTERP, SELF);
-
-        /* we're done reading the image */
-        PARROT_ASSERT(!INFO_HAS_DATA(SELF));
-        Parrot_visit_loop_thawfinish(INTERP, SELF);
-    }
-
-
-/*
-
-=back
-
-=cut
-
-*/
-
-}
-
-/*
- * Local variables:
- *   c-file-style: "parrot"
- * End:
- * vim: expandtab shiftwidth=4:
- */

Added: trunk/src/pmc/imageiofreeze.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/pmc/imageiofreeze.pmc	Sat Sep 18 03:47:34 2010	(r49130)
@@ -0,0 +1,554 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id: imageio.pmc 49125 2010-09-18 00:48:46Z plobsing $
+
+=head1 NAME
+
+src/pmc/imageiofreeze.pmc - ImageIOFreeze PMC
+
+=head1 DESCRIPTION
+
+Freezes other PMCs.
+
+=head1 FUNCTIONS
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/imageio.h"
+
+/* HEADERIZER HFILE: none */
+/* 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(PMC *info))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*info);
+
+PARROT_INLINE
+static void ensure_buffer_size(PARROT_INTERP, ARGIN(PMC *io), size_t len)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_INLINE
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+static opcode_t * GET_VISIT_CURSOR(ARGIN(const PMC *pmc))
+        __attribute__nonnull__(1);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+PARROT_INLINE
+static PMC* id_list_get(PARROT_INTERP, ARGIN(const PMC *io), UINTVAL id)
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_INLINE
+static void INC_VISIT_CURSOR(ARGMOD(PMC *pmc), UINTVAL inc)
+        __attribute__nonnull__(1)
+        FUNC_MODIFIES(*pmc);
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_INLINE
+static INTVAL INFO_HAS_DATA(ARGIN(const PMC *io))
+        __attribute__nonnull__(1);
+
+PARROT_INLINE
+static void SET_VISIT_CURSOR(ARGMOD(PMC *pmc), ARGIN(const char *cursor))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(*pmc);
+
+#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_CURSOR __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(pmc))
+#define ASSERT_ARGS_id_list_get __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(io))
+#define ASSERT_ARGS_INC_VISIT_CURSOR __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(pmc))
+#define ASSERT_ARGS_INFO_HAS_DATA __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(io))
+#define ASSERT_ARGS_SET_VISIT_CURSOR __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(pmc) \
+    , PARROT_ASSERT_ARG(cursor))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: static */
+
+/*
+
+=item C<static opcode_t * GET_VISIT_CURSOR(const PMC *pmc)>
+
+=cut
+
+*/
+
+PARROT_INLINE
+PARROT_CANNOT_RETURN_NULL
+PARROT_WARN_UNUSED_RESULT
+static opcode_t *
+GET_VISIT_CURSOR(ARGIN(const PMC *pmc))
+{
+    ASSERT_ARGS(GET_VISIT_CURSOR)
+
+    char * const buf = (char *)Buffer_bufstart(PARROT_IMAGEIOFREEZE(pmc)->buffer);
+    const size_t pos = PARROT_IMAGEIOFREEZE(pmc)->pos;
+    return (opcode_t *)(buf + pos);
+}
+
+/*
+
+=item C<static void SET_VISIT_CURSOR(PMC *pmc, const char *cursor)>
+
+=cut
+
+*/
+
+
+PARROT_INLINE
+static void
+SET_VISIT_CURSOR(ARGMOD(PMC *pmc), ARGIN(const char *cursor))
+{
+    ASSERT_ARGS(SET_VISIT_CURSOR)
+
+    const char * const bufstart  = (const char *)Buffer_bufstart(PARROT_IMAGEIOFREEZE(pmc)->buffer);
+    PARROT_IMAGEIOFREEZE(pmc)->pos = (cursor - bufstart);
+}
+
+/*
+
+=item C<static void INC_VISIT_CURSOR(PMC *pmc, UINTVAL inc)>
+
+=cut
+
+*/
+
+
+PARROT_INLINE
+static void
+INC_VISIT_CURSOR(ARGMOD(PMC *pmc), UINTVAL inc)
+{
+    ASSERT_ARGS(INC_VISIT_CURSOR)
+
+    PARROT_IMAGEIOFREEZE(pmc)->pos += inc;
+}
+
+
+/*
+
+=item C<static void create_buffer(PARROT_INTERP, PMC *pmc, PMC *info)>
+
+=cut
+
+*/
+
+static void
+create_buffer(PARROT_INTERP, ARGIN_NULLOK(PMC *pmc), ARGMOD(PMC *info))
+{
+    ASSERT_ARGS(create_buffer)
+
+    INTVAL  len;
+
+    if (!PMC_IS_NULL(pmc)) {
+        STRING * const array = CONST_STRING(interp, "array");
+        STRING * const 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_IMAGEIOFREEZE(info)->buffer =
+        Parrot_gc_new_bufferlike_header(interp, sizeof (Buffer));
+    Parrot_gc_allocate_buffer_storage_aligned(interp,
+        PARROT_IMAGEIOFREEZE(info)->buffer, len);
+    SET_VISIT_CURSOR(info,
+        (const char *)Buffer_bufstart(PARROT_IMAGEIOFREEZE(info)->buffer));
+}
+
+/*
+
+=item C<static void ensure_buffer_size(PARROT_INTERP, PMC *io, size_t len)>
+
+Checks the size of the buffer to see if it can accommodate C<len> more
+bytes. If not, expands the buffer.
+
+=cut
+
+*/
+
+PARROT_INLINE
+static void
+ensure_buffer_size(PARROT_INTERP, ARGIN(PMC *io), size_t len)
+{
+    ASSERT_ARGS(ensure_buffer_size)
+
+    Buffer * const buf  = PARROT_IMAGEIOFREEZE(io)->buffer;
+    const size_t used   = PARROT_IMAGEIOFREEZE(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 PMC* id_list_get(PARROT_INTERP, const PMC *io, UINTVAL id)>
+
+=cut
+
+*/
+
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+PARROT_INLINE
+static PMC*
+id_list_get(PARROT_INTERP, ARGIN(const PMC *io), UINTVAL id)
+{
+    ASSERT_ARGS(id_list_get)
+
+    return VTABLE_get_pmc_keyed_int(interp, PARROT_IMAGEIOFREEZE(io)->todo, id - 1);
+}
+
+pmclass ImageIOFreeze auto_attrs {
+    ATTR Buffer              *buffer;      /* buffer to store the image */
+    ATTR size_t               pos;         /* current read/write buf position */
+    ATTR PMC                 *seen;        /* seen hash */
+    ATTR PMC                 *todo;        /* todo list */
+    ATTR UINTVAL              id;          /* freze ID of PMC */
+    ATTR struct PackFile     *pf;
+    ATTR PackFile_ConstTable *pf_ct;
+
+/*
+
+=back
+
+=head1 VTABLES
+
+=over 4
+
+=cut
+
+*/
+
+/*
+
+=item C<void init()>
+
+Initializes the PMC.
+
+=cut
+
+*/
+    VTABLE void init() {
+        PARROT_IMAGEIOFREEZE(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash);
+        VTABLE_set_pointer(INTERP, PARROT_IMAGEIOFREEZE(SELF)->seen,
+            parrot_new_intval_hash(INTERP));
+
+        PARROT_IMAGEIOFREEZE(SELF)->todo =
+            Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+
+        PObj_flag_CLEAR(private1, SELF);
+
+        PObj_custom_mark_SET(SELF);
+    }
+
+
+/*
+
+=item C<void destroy()>
+
+Destroys the PMC.
+
+=cut
+
+*/
+    VTABLE void destroy() {
+        PackFile_destroy(INTERP, PARROT_IMAGEIOFREEZE(SELF)->pf);
+        PARROT_IMAGEIOFREEZE(SELF)->pf = NULL;
+    }
+
+
+/*
+
+=item C<void mark()>
+
+Marks the PMC as alive.
+
+=cut
+
+*/
+    VTABLE void mark() {
+        PObj * const buffer = (PObj *)(PARROT_IMAGEIOFREEZE(SELF)->buffer);
+        if (buffer)
+            Parrot_gc_mark_PObj_alive(INTERP, buffer);
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOFREEZE(SELF)->todo);
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOFREEZE(SELF)->seen);
+    }
+
+
+/*
+
+=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_IMAGEIOFREEZE(SELF)->buffer,
+                                          PARROT_IMAGEIOFREEZE(SELF)->pos);
+    }
+
+
+/*
+
+=item C<VTABLE PMC *get_iter()>
+
+Get the C<todo> list for this freeze/thaw for iterating over.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_iter() {
+        return PARROT_IMAGEIOFREEZE(SELF)->todo;
+    }
+
+/*
+
+=item C<VTABLE INTVAL get_integer()>
+
+Returns the flags describing the visit action.
+
+=cut
+
+*/
+
+    VTABLE INTVAL get_integer() {
+        return VISIT_FREEZE_NORMAL;
+    }
+
+
+/*
+
+=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) {
+        const size_t len = PF_size_integer() * sizeof (opcode_t);
+        ensure_buffer_size(INTERP, SELF, len);
+        SET_VISIT_CURSOR(SELF,
+            (const 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) {
+        const size_t len = PF_size_number() * sizeof (opcode_t);
+        ensure_buffer_size(INTERP, SELF, len);
+        SET_VISIT_CURSOR(SELF,
+            (const 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) {
+        if (PObj_flag_TEST(private1, SELF)) {
+            /* store a reference to constant table entry of string */
+            PMC                 * const v_pmc = key_new_string(interp, v);
+            PackFile_ConstTable * const table = PARROT_IMAGEIOFREEZE(SELF)->pf_ct;
+            const int idx =
+                PackFile_ConstTable_rlookup(INTERP, table, v_pmc, PFC_STRING);
+
+            if (idx >= 0) {
+                STATICSELF.push_integer(idx);
+                return;
+            }
+
+            /* XXX handle cases where the PMC has changed after
+             * Parrot_freeze_strings was called eg: :immediate subs */
+            STATICSELF.push_integer(-1);
+
+            /* TODO
+             * should really be:
+             * PANIC(INTERP, "string not previously in constant table "
+             *               "when freezing to packfile"); */
+        }
+
+        {
+            const size_t len = PF_size_string(v) * sizeof (opcode_t);
+            ensure_buffer_size(INTERP, SELF, len);
+            SET_VISIT_CURSOR(SELF,
+                (const 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) {
+        UINTVAL id;
+        int packid_type;
+
+        if (PMC_IS_NULL(v)) {
+            id   = 0;
+            packid_type = enum_PackID_seen;
+        }
+        else {
+            Hash * const hash = (Hash *)VTABLE_get_pointer(INTERP,
+                    PARROT_IMAGEIOFREEZE(SELF)->seen);
+            HashBucket * const b = parrot_hash_get_bucket(INTERP, hash, v);
+
+            if (b) {
+                id = (UINTVAL)b->value;
+                packid_type = enum_PackID_seen;
+            }
+            else {
+                ++PARROT_IMAGEIOFREEZE(SELF)->id; /* next id to freeze */
+                id = PARROT_IMAGEIOFREEZE(SELF)->id;
+                packid_type = enum_PackID_normal;
+            }
+        }
+
+        SELF.push_integer(PackID_new(id, packid_type));
+
+        if (packid_type == enum_PackID_normal) {
+            Hash * const hash = (Hash *)VTABLE_get_pointer(INTERP,
+                    PARROT_IMAGEIOFREEZE(SELF)->seen);
+
+            PARROT_ASSERT(v);
+
+            /* workaround to keep ParrotInterpreter PBC hack working */
+            if (v->vtable->base_type == enum_class_ParrotInterpreter)
+                PObj_flag_CLEAR(private1, SELF);
+
+            SELF.push_integer(
+                    PObj_is_object_TEST(v)
+                    ? (INTVAL) enum_class_Object
+                    : v->vtable->base_type);
+
+            parrot_hash_put(INTERP, hash, v, (void *)id);
+            VTABLE_push_pmc(INTERP, PARROT_IMAGEIOFREEZE(SELF)->todo, v);
+        }
+    }
+
+
+/*
+
+=item C<void set_pointer(void *value)>
+
+Sets the constant table of this ImageIO PMC.
+
+=cut
+
+*/
+
+    VTABLE void set_pointer(void *value) {
+        PObj_flag_SET(private1, SELF);
+        PARROT_IMAGEIOFREEZE(SELF)->pf_ct = (PackFile_ConstTable *)value;
+    }
+
+
+    VTABLE void set_pmc(PMC *p)
+    {
+        create_buffer(INTERP, p, SELF);
+
+        if (PObj_flag_TEST(private1, SELF)) {
+            PARROT_IMAGEIOFREEZE(SELF)->pf = PARROT_IMAGEIOFREEZE(SELF)->pf_ct->base.pf;
+        }
+        else {
+            const UINTVAL header_length =
+                GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+
+            PARROT_IMAGEIOFREEZE(SELF)->pf = PackFile_new(INTERP, 0);
+            PObj_custom_destroy_SET(SELF);
+
+            ensure_buffer_size(INTERP, SELF, header_length);
+            mem_sys_memcopy(GET_VISIT_CURSOR(SELF),
+                PARROT_IMAGEIOFREEZE(SELF)->pf->header, PACKFILE_HEADER_BYTES);
+            INC_VISIT_CURSOR(SELF, header_length);
+        }
+
+        STATICSELF.push_pmc(p);
+        Parrot_visit_loop_visit(INTERP, SELF);
+    }
+}
+
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: trunk/src/pmc_freeze.c
==============================================================================
--- trunk/src/pmc_freeze.c	Sat Sep 18 03:22:55 2010	(r49129)
+++ trunk/src/pmc_freeze.c	Sat Sep 18 03:47:34 2010	(r49130)
@@ -54,7 +54,7 @@
 Parrot_freeze(PARROT_INTERP, ARGIN(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_freeze)
-    PMC * const image = Parrot_pmc_new(interp, enum_class_ImageIO);
+    PMC * const image = Parrot_pmc_new(interp, enum_class_ImageIOFreeze);
     VTABLE_set_pmc(interp, image, pmc);
     return VTABLE_get_string(interp, image);
 }
@@ -83,7 +83,7 @@
     STRING *image;
     DECL_CONST_CAST;
 
-    visitor  = Parrot_pmc_new(interp, enum_class_ImageIO);
+    visitor  = Parrot_pmc_new(interp, enum_class_ImageIOFreeze);
     VTABLE_set_pointer(interp, visitor,
         PARROT_const_cast(void *, (const void *)pf));
     VTABLE_set_pmc(interp, visitor, pmc);

Modified: trunk/t/pmc/imageio.t
==============================================================================
--- trunk/t/pmc/imageio.t	Sat Sep 18 03:22:55 2010	(r49129)
+++ trunk/t/pmc/imageio.t	Sat Sep 18 03:47:34 2010	(r49130)
@@ -4,7 +4,7 @@
 
 =head1 NAME
 
-t/pmc/imageio.t - test ImageIO PMC
+t/pmc/imageio.t - test ImageIOFreeze and ImageIOThaw PMC
 
 =head1 SYNOPSIS
 
@@ -19,39 +19,41 @@
 .sub main :main
     .include 'test_more.pir'
 
-    plan(11)
+    plan(12)
 
-    .local pmc imageio
-    imageio = new ['ImageIO']
-    ok(1, 'instantiated ImageIO')
+    .local pmc frz, thw
+    frz = new ['ImageIOFreeze']
+    ok(1, 'instantiated ImageIOFreeze')
+
+    thw = new ['ImageIOThaw']
+    ok(1, 'instantiated ImageIOThaw')
 
     .local pmc test_pmc
     test_pmc = 'get_test_simple'()
-    setref imageio, test_pmc
-    $S0 = imageio
+    setref frz, test_pmc
+    $S0 = frz
     ok($S0, 'frozen PMC is true (simple)')
     $S1 = freeze test_pmc
     is($S0, $S1, 'freeze gives same image as ImageIO (simple)')
 
-    imageio = new ['ImageIO']
-    imageio = $S0
-    $P0 = deref imageio
+    thw = $S0
+    $P0 = deref thw
     ok($P0, 'thawed PMC is true (simple)')
     $P1 = thaw $S1
     is($P0, $P1, 'thaw gives same PMC as ImageIO (simple)')
     is($P0, test_pmc, 'round trip gives same PMC (simple)')
 
-    imageio = new ['ImageIO']
+    frz = new ['ImageIOFreeze']
     test_pmc = 'get_test_aggregate'()
-    setref imageio, test_pmc
-    $S0 = imageio
+    setref frz, test_pmc
+    $S0 = frz
     ok($S0, 'frozen PMC is true (aggregate)')
     $S1 = freeze test_pmc
     is($S0, $S1, 'freeze gives same image as ImageIO (aggregate)')
 
-    imageio = new ['ImageIO']
-    imageio = $S0
-    $P0 = deref imageio
+    thw = new ['ImageIOThaw']
+    thw = $S0
+    $P0 = deref thw
     ok($P0, 'thawed PMC is true (aggregate)')
     $P1 = thaw $S1
     is_deeply($P0, $P1, 'thaw gives same PMC as ImageIO (aggregate)')


More information about the parrot-commits mailing list