[svn:parrot] r44214 - 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 src src/call src/gc src/interp src/pmc src/runcore t/compilers/tge t/native_pbc t/oo t/pmc t/src t/steps/init/hints tools/build tools/dev tools/util

plobsing at svn.parrot.org plobsing at svn.parrot.org
Sat Feb 20 02:01:12 UTC 2010


Author: plobsing
Date: Sat Feb 20 02:01:10 2010
New Revision: 44214
URL: https://trac.parrot.org/parrot/changeset/44214

Log:
merge branch tt362

Added:
   trunk/src/pmc/imageiosize.pmc
      - copied unchanged from r44212, branches/tt362/src/pmc/imageiosize.pmc
   trunk/t/pmc/imageio.t
      - copied unchanged from r44212, branches/tt362/t/pmc/imageio.t
   trunk/t/pmc/imageiosize.t
      - copied unchanged from r44212, branches/tt362/t/pmc/imageiosize.t
Modified:
   trunk/   (props changed)
   trunk/MANIFEST
   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/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/interp/inter_cb.c   (props changed)
   trunk/src/interp/inter_create.c   (props changed)
   trunk/src/interp/inter_misc.c   (props changed)
   trunk/src/packfile.c
   trunk/src/pmc/imageio.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/t/compilers/tge/NoneGrammar.tg   (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	Sat Feb 20 01:36:20 2010	(r44213)
+++ trunk/MANIFEST	Sat Feb 20 02:01:10 2010	(r44214)
@@ -1431,6 +1431,7 @@
 src/pmc/hashiterator.pmc                                    [devel]src
 src/pmc/hashiteratorkey.pmc                                 [devel]src
 src/pmc/imageio.pmc                                         [devel]src
+src/pmc/imageiosize.pmc                                     [devel]src
 src/pmc/integer.pmc                                         [devel]src
 src/pmc/iterator.pmc                                        [devel]src
 src/pmc/key.pmc                                             [devel]src
@@ -1899,6 +1900,8 @@
 t/pmc/hash.t                                                [test]
 t/pmc/hashiterator.t                                        [test]
 t/pmc/hashiteratorkey.t                                     [test]
+t/pmc/imageio.t                                             [test]
+t/pmc/imageiosize.t                                         [test]
 t/pmc/integer.t                                             [test]
 t/pmc/io.t                                                  [test]
 t/pmc/io_iterator.t                                         [test]

Modified: trunk/include/parrot/pmc_freeze.h
==============================================================================
--- trunk/include/parrot/pmc_freeze.h	Sat Feb 20 01:36:20 2010	(r44213)
+++ trunk/include/parrot/pmc_freeze.h	Sat Feb 20 02:01:10 2010	(r44214)
@@ -13,9 +13,6 @@
 #ifndef PARROT_PMC_FREEZE_H_GUARD
 #define PARROT_PMC_FREEZE_H_GUARD
 
-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 */
     VISIT_HOW_VISITOR_TO_PMC     = 0x01, /* shift from visitor */
@@ -124,6 +121,13 @@
 PARROT_EXPORT
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
+INTVAL Parrot_freeze_size(PARROT_INTERP, ARGIN(PMC *pmc))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
 PMC* Parrot_thaw(PARROT_INTERP, ARGIN(STRING *image))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -135,18 +139,35 @@
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
 
+void Parrot_visit_loop_thawfinish(PARROT_INTERP, ARGIN(PMC *info))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+void Parrot_visit_loop_visit(PARROT_INTERP, ARGIN(PMC *info))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 #define ASSERT_ARGS_Parrot_clone __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(pmc))
 #define ASSERT_ARGS_Parrot_freeze __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(pmc))
+#define ASSERT_ARGS_Parrot_freeze_size __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(pmc))
 #define ASSERT_ARGS_Parrot_thaw __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(image))
 #define ASSERT_ARGS_Parrot_thaw_constants __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(image))
+#define ASSERT_ARGS_Parrot_visit_loop_thawfinish __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(info))
+#define ASSERT_ARGS_Parrot_visit_loop_visit __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: src/pmc_freeze.c */
 

Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c	Sat Feb 20 01:36:20 2010	(r44213)
+++ trunk/src/packfile.c	Sat Feb 20 02:01:10 2010	(r44214)
@@ -3866,7 +3866,6 @@
 {
     ASSERT_ARGS(PackFile_Constant_pack_size)
     PMC    *component;
-    STRING *image;
     size_t  packed_size;
 
     switch (self->type) {
@@ -3890,13 +3889,8 @@
       case PFC_PMC:
         component = self->u.key; /* the pmc (Sub, ...) */
 
-        /*
-         * TODO create either
-         * a) a frozen_size freeze entry or
-         * b) change packout.c so that component size isn't needed
-         */
-        image       = Parrot_freeze(interp, component);
-        packed_size = PF_size_string(image);
+        packed_size =
+            PF_size_string(STRINGNULL) + Parrot_freeze_size(interp, component) / sizeof (opcode_t);
         break;
 
       default:

Modified: trunk/src/pmc/imageio.pmc
==============================================================================
--- trunk/src/pmc/imageio.pmc	Sat Feb 20 01:36:20 2010	(r44213)
+++ trunk/src/pmc/imageio.pmc	Sat Feb 20 02:01:10 2010	(r44214)
@@ -10,6 +10,8 @@
 
 Freezes and thaws other PMCs.
 
+=cut
+
 */
 
 #define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
@@ -123,12 +125,12 @@
 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);
+    return VTABLE_get_pmc_keyed_int(interp, PARROT_IMAGEIO(io)->todo, id - 1);
 }
 
 PARROT_INLINE
-static void
-visit_todo_list_thaw(PARROT_INTERP, SHIM(PMC* pmc_not_used), ARGIN(PMC* info))
+static PMC *
+visit_todo_list_thaw(PARROT_INTERP, ARGIN(PMC* info))
 {
     UINTVAL  n            = VTABLE_shift_integer(interp, info);
     UINTVAL  id           = PackID_get_PMCID(n);
@@ -153,10 +155,7 @@
 
             {
                 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_push_pmc(interp, todo, pmc);
+                VTABLE_set_pmc_keyed_int(interp, todo, id - 1, pmc);
             }
         }
         break;
@@ -165,7 +164,7 @@
         break;
     }
 
-    *(PARROT_IMAGEIO(info)->thaw_ptr) = pmc;
+    return pmc;
 }
 
 static void
@@ -207,65 +206,14 @@
     }
 }
 
-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_pop_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;
 
 /*
@@ -288,13 +236,10 @@
 
 */
     VTABLE void init() {
-        PARROT_IMAGEIO(SELF)->thaw_ptr    = NULL;
         PARROT_IMAGEIO(SELF)->buffer      = NULL;
         PARROT_IMAGEIO(SELF)->todo        = Parrot_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);
@@ -329,7 +274,6 @@
             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);
     }
 
 /*
@@ -347,20 +291,33 @@
                                           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 void set_pointer()>
+=item C<VTABLE PMC *get_iter()>
 
-Sets the location where to thaw a new PMC.
+Get the C<todo> list for this freeze/thaw for iterating over.
 
 =cut
 
 */
 
-    VTABLE void set_pointer(void* value) {
-        PARROT_IMAGEIO(SELF)->thaw_ptr = (PMC**)value;
+    VTABLE PMC *get_iter() {
+        return PARROT_IMAGEIO(SELF)->todo;
     }
 
 /*
@@ -441,8 +398,7 @@
 */
 
     VTABLE void push_pmc(PMC *v) {
-        VTABLE_set_pointer(interp, SELF, &v);
-        (PARROT_IMAGEIO(SELF)->visit_pmc_now)(INTERP, v, SELF);
+        visit_todo_list_freeze(INTERP, v, SELF);
     }
 
 /*
@@ -515,60 +471,59 @@
 */
 
     VTABLE PMC *shift_pmc() {
-        PMC *result;
-        VTABLE_set_pointer(interp, SELF, &result);
-        (PARROT_IMAGEIO(SELF)->visit_pmc_now)(interp, NULL, SELF);
-        return result;
+        return visit_todo_list_thaw(INTERP, SELF);
     }
 
     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);
+        UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
 
-            PARROT_IMAGEIO(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash);
-            VTABLE_set_pointer(INTERP, PARROT_IMAGEIO(SELF)->seen,
-                parrot_new_intval_hash(INTERP));
+        PARROT_IMAGEIO(SELF)->what = VISIT_FREEZE_NORMAL;
+        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 = Parrot_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);
+        visit_todo_list_freeze(INTERP, p, SELF);
+        Parrot_visit_loop_visit(INTERP, SELF);
     }
 
     VTABLE void set_string_native(STRING *image) {
-            UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
-            int unpacked_length;
+        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       = Parrot_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);
-            }
+        PARROT_IMAGEIO(SELF)->what          = VISIT_THAW_NORMAL;
+        PARROT_IMAGEIO(SELF)->buffer        = (Buffer *)image;
 
-            visit_loop_todo_list(interp, pmc, SELF);
+        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_todo_list_thaw(INTERP, SELF);
+        Parrot_visit_loop_visit(INTERP, SELF);
+
+        /* we're done reading the image */
+        PARROT_ASSERT(!INFO_HAS_DATA(SELF));
+        Parrot_visit_loop_thawfinish(INTERP, SELF);
     }
 
 /*

Copied: trunk/src/pmc/imageiosize.pmc (from r44212, branches/tt362/src/pmc/imageiosize.pmc)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/src/pmc/imageiosize.pmc	Sat Feb 20 02:01:10 2010	(r44214, copy of r44212, branches/tt362/src/pmc/imageiosize.pmc)
@@ -0,0 +1,237 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/pmc/imageiosize.pmc - ImageIOSize PMC
+
+=head1 DESCRIPTION
+
+Gets the size of an ImageIO image without the allocation costs.
+
+=cut
+
+*/
+
+#define GROW_TO_16_BYTE_BOUNDARY(size) ((size) + ((size) % 16 ? 16 - (size) % 16 : 0))
+
+static void
+visit_todo_list_freeze(PARROT_INTERP, PMC* pmc, PMC* info) {
+    int is_new = 0;
+
+    if (!PMC_IS_NULL(pmc)) {
+        Hash *hash = (Hash *)VTABLE_get_pointer(interp, PARROT_IMAGEIOSIZE(info)->seen);
+        HashBucket * const b = parrot_hash_get_bucket(interp, hash, pmc);
+        is_new = !b;
+    }
+
+    VTABLE_push_integer(interp, info, 0);
+
+    if (is_new) {
+        Hash *hash = (Hash *)VTABLE_get_pointer(interp, PARROT_IMAGEIOSIZE(info)->seen);
+        parrot_hash_put(interp, hash, pmc, pmc);
+        VTABLE_push_integer(interp, info, pmc->vtable->base_type);
+        VTABLE_push_pmc(interp, PARROT_IMAGEIOSIZE(info)->todo, pmc);
+        VTABLE_freeze(interp, pmc, info);
+    }
+}
+
+pmclass ImageIOSize auto_attrs {
+    ATTR PMC             *seen;           /* seen hash */
+    ATTR PMC             *todo;           /* todo list */
+    ATTR struct PackFile *pf;
+    ATTR INTVAL           size;
+
+/*
+
+=head1 VTABLES
+
+=over 4
+
+=cut
+
+*/
+
+/*
+
+=item C<void init()>
+
+Initializes the PMC.
+
+=cut
+
+*/
+    VTABLE void init() {
+        PARROT_IMAGEIOSIZE(SELF)->todo = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+        PARROT_IMAGEIOSIZE(SELF)->pf   = PackFile_new(INTERP, 0);
+        PARROT_IMAGEIOSIZE(SELF)->size = 0;
+
+        PARROT_IMAGEIOSIZE(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash);
+        VTABLE_set_pointer(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen,
+            parrot_new_intval_hash(INTERP));
+
+        PObj_custom_mark_destroy_SETALL(SELF);
+    }
+
+
+/*
+
+=item C<void destroy()>
+
+Destroys the PMC.
+
+=cut
+
+*/
+    VTABLE void destroy() {
+        PackFile_destroy(INTERP, PARROT_IMAGEIOSIZE(SELF)->pf);
+    }
+
+/*
+
+=item C<void mark()>
+
+Marks the PMC as alive.
+
+=cut
+
+*/
+    VTABLE void mark() {
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->todo);
+        Parrot_gc_mark_PMC_alive(INTERP, PARROT_IMAGEIOSIZE(SELF)->seen);
+    }
+
+/*
+
+=item C<VTABLE PMC *get_pmc()>
+
+Gets the result PMC after a thaw.
+
+=cut
+
+*/
+
+    VTABLE PMC *get_pmc() {
+        PMC *ret = Parrot_pmc_new(INTERP, enum_class_Integer);
+        VTABLE_set_integer_native(INTERP, ret, PARROT_IMAGEIOSIZE(SELF)->size);
+        return ret;
+    }
+
+/*
+
+=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_IMAGEIOSIZE(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) {
+        size_t len = PF_size_integer() * sizeof (opcode_t);
+        PARROT_IMAGEIOSIZE(SELF)->size += len;
+    }
+
+
+/*
+
+=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);
+        PARROT_IMAGEIOSIZE(SELF)->size += len;
+    }
+
+
+/*
+
+=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);
+        PARROT_IMAGEIOSIZE(SELF)->size += len;
+    }
+
+/*
+
+=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) {
+        visit_todo_list_freeze(INTERP, v, SELF);
+    }
+
+    VTABLE void set_pmc(PMC *p)
+    {
+        UINTVAL header_length = GROW_TO_16_BYTE_BOUNDARY(PACKFILE_HEADER_BYTES);
+        PARROT_IMAGEIOSIZE(SELF)->size += header_length;
+
+        visit_todo_list_freeze(INTERP, p, SELF);
+        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 Feb 20 01:36:20 2010	(r44213)
+++ trunk/src/pmc_freeze.c	Sat Feb 20 02:01:10 2010	(r44214)
@@ -59,6 +59,32 @@
     return VTABLE_get_string(interp, image);
 }
 
+/*
+
+=item C<INTVAL Parrot_freeze_size(PARROT_INTERP, PMC *pmc)>
+
+Get the size of an image to be frozen without allocating a large buffer.
+
+Used in C<Packfile_Constant_pack_size>.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_WARN_UNUSED_RESULT
+PARROT_CAN_RETURN_NULL
+INTVAL
+Parrot_freeze_size(PARROT_INTERP, ARGIN(PMC *pmc))
+{
+    ASSERT_ARGS(Parrot_freeze_size)
+    PMC *result;
+    PMC *visitor = Parrot_pmc_new(interp, enum_class_ImageIOSize);
+    VTABLE_set_pmc(interp, visitor, pmc);
+    result = VTABLE_get_pmc(interp, visitor);
+    return VTABLE_get_integer(interp, result);
+}
+
 
 /*
 
@@ -105,8 +131,8 @@
         gc_block = 1;
     }
 
-    VTABLE_set_pointer(interp, info, &result);
     VTABLE_set_string_native(interp, info, image);
+    result = VTABLE_get_pmc(interp, info);
 
     if (gc_block) {
         Parrot_unblock_GC_mark(interp);
@@ -160,6 +186,72 @@
     return VTABLE_clone(interp, pmc);
 }
 
+/*
+
+=item C<void Parrot_visit_loop_visit(PARROT_INTERP, PMC *info)>
+
+Iterate a visitor PMC visiting each encountered target PMC.
+
+=cut
+
+*/
+
+void
+Parrot_visit_loop_visit(PARROT_INTERP, ARGIN(PMC *info)) {
+    ASSERT_ARGS(Parrot_visit_loop_visit)
+
+    INTVAL      i;
+    PMC * const todo    = VTABLE_get_iter(interp, info);
+
+    /* can't cache upper limit, visit may append items */
+    for (i = 0; i < VTABLE_elements(interp, todo); i++) {
+        PMC *current = VTABLE_get_pmc_keyed_int(interp, todo, i);
+        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));
+    }
+}
+
+/*
+
+=item C<void Parrot_visit_loop_thawfinish(PARROT_INTERP, PMC *info)>
+
+Iterate a visitor PMC thawfinishing each encountered target PMC.
+
+=cut
+
+*/
+
+void
+Parrot_visit_loop_thawfinish(PARROT_INTERP, ARGIN(PMC *info)) {
+    ASSERT_ARGS(Parrot_visit_loop_thawfinish)
+
+    /* call thawfinish for each processed PMC */
+    /*
+     * 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.
+     */
+
+    PMC * const todo    = VTABLE_get_iter(interp, info);
+    const INTVAL n = VTABLE_elements(interp, todo);
+    int          i;
+
+    for (i = n-1; i >= 0; --i) {
+        PMC *current = VTABLE_get_pmc_keyed_int(interp, todo, i);
+        if (!PMC_IS_NULL(current))
+            VTABLE_thawfinish(interp, current, info);
+    }
+}
 
 /*
 

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.

Copied: trunk/t/pmc/imageio.t (from r44212, branches/tt362/t/pmc/imageio.t)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/t/pmc/imageio.t	Sat Feb 20 02:01:10 2010	(r44214, copy of r44212, branches/tt362/t/pmc/imageio.t)
@@ -0,0 +1,79 @@
+#! parrot
+# Copyright (C) 2010, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+t/pmc/imageio.t - test ImageIO PMC
+
+=head1 SYNOPSIS
+
+    % prove t/pmc/imagio.t
+
+=head1 DESCRIPTION
+
+Tests the ImageIO PMC.
+
+=cut
+
+.sub main :main
+    .include 'test_more.pir'
+
+    plan(11)
+
+    .local pmc imageio
+    imageio = new ['ImageIO']
+    ok(1, 'instantiated ImageIO')
+
+    .local pmc test_pmc
+    test_pmc = 'get_test_simple'()
+    setref imageio, test_pmc
+    $S0 = imageio
+    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
+    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']
+    test_pmc = 'get_test_aggregate'()
+    setref imageio, test_pmc
+    $S0 = imageio
+    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
+    ok($P0, 'thawed PMC is true (aggregate)')
+    $P1 = thaw $S1
+    is_deeply($P0, $P1, 'thaw gives same PMC as ImageIO (aggregate)')
+    is_deeply($P0, test_pmc, 'round trip gives same PMC (aggregate)')
+.end
+
+.sub get_test_simple
+    $P0 = new ['Integer']
+    $P0 = -99
+    .return ($P0)
+.end
+
+.sub get_test_aggregate
+    $P0 = new ['ResizableStringArray']
+    $P0[0] = 'parrot'
+    $P0[1] = '???'
+    $P0[2] = 'profit'
+    .return ($P0)
+.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir

Copied: trunk/t/pmc/imageiosize.t (from r44212, branches/tt362/t/pmc/imageiosize.t)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/t/pmc/imageiosize.t	Sat Feb 20 02:01:10 2010	(r44214, copy of r44212, branches/tt362/t/pmc/imageiosize.t)
@@ -0,0 +1,74 @@
+#! parrot
+# Copyright (C) 2010, Parrot Foundation.
+# $Id$
+
+=head1 NAME
+
+t/pmc/imageiosize.t - test ImageIOSize PMC
+
+=head1 SYNOPSIS
+
+    % prove t/pmc/imagiosize.t
+
+=head1 DESCRIPTION
+
+Tests the ImageIOSize PMC.
+
+=cut
+
+.sub main :main
+    .include 'test_more.pir'
+
+    plan(4)
+
+    .local pmc iios
+    iios = new ['ImageIOSize']
+    ok(1, 'instantiated ImageIOSize')
+
+    .local pmc test_pmc
+    test_pmc = null
+    setref iios, test_pmc
+    $P0 = deref iios
+    $S0 = freeze test_pmc
+    $I0 = $P0
+    $I1 = length $S0
+    is($I0, $I1, 'gets the same size as freeze (null)')
+
+    iios = new ['ImageIOSize']
+    test_pmc = 'get_test_simple'()
+    setref iios, test_pmc
+    $P0 = deref iios
+    $S0 = freeze test_pmc
+    $I0 = $P0
+    $I1 = length $S0
+    is($I0, $I1, 'gets the same size as freeze (simple)')
+
+    iios = new ['ImageIOSize']
+    test_pmc = 'get_test_aggregate'()
+    setref iios, test_pmc
+    $P0 = deref iios
+    $S0 = freeze test_pmc
+    $I0 = $P0
+    $I1 = length $S0
+    is($I0, $I1, 'gets the same size as freeze (aggregate)')
+.end
+
+.sub get_test_simple
+    $P0 = new ['Integer']
+    $P0 = -99
+    .return ($P0)
+.end
+
+.sub get_test_aggregate
+    $P0 = new ['ResizableStringArray']
+    $P0[0] = 'parrot'
+    $P0[1] = '???'
+    $P0[2] = 'profit'
+    .return ($P0)
+.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir


More information about the parrot-commits mailing list