[svn:parrot] r43670 - branches/pmc_freeze_with_pmcs/src/pmc
darbelo at svn.parrot.org
darbelo at svn.parrot.org
Mon Feb 1 00:44:52 UTC 2010
Author: darbelo
Date: Mon Feb 1 00:44:51 2010
New Revision: 43670
URL: https://trac.parrot.org/parrot/changeset/43670
Log:
Copy private support routines, from pmc_freeze.c to the ImageIO PMC. We should be done shuffling code for now.
Modified:
branches/pmc_freeze_with_pmcs/src/pmc/imageio.pmc
Modified: branches/pmc_freeze_with_pmcs/src/pmc/imageio.pmc
==============================================================================
--- branches/pmc_freeze_with_pmcs/src/pmc/imageio.pmc Mon Feb 1 00:40:55 2010 (r43669)
+++ branches/pmc_freeze_with_pmcs/src/pmc/imageio.pmc Mon Feb 1 00:44:51 2010 (r43670)
@@ -62,6 +62,32 @@
+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)
@@ -93,6 +119,147 @@
}
+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) {
+ List * const id_list = (List *)PMC_data(PARROT_IMAGEIO(io)->id_list);
+ PMC **pos = (PMC **)Parrot_pmc_array_get(interp, id_list, id, enum_type_PMC);
+
+ if (pos && pos != ((void *)-1))
+ return *pos;
+ return NULL;
+}
+
+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);
+
+ {
+ List * const todo = (List *)PMC_data(PARROT_IMAGEIO(info)->todo);
+ List * const id_list = (List *)PMC_data(PARROT_IMAGEIO(info)->id_list);
+ Parrot_pmc_array_assign(interp, id_list, id, pmc, enum_type_PMC);
+ /* remember nested aggregates depth first */
+ Parrot_pmc_array_unshift(interp, todo, pmc, enum_type_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);
+ Parrot_pmc_array_unshift(interp,
+ (List *)PMC_data(PARROT_IMAGEIO(info)->todo), pmc, enum_type_PMC);
+ VTABLE_freeze(interp, pmc, info);
+ }
+}
+
+static void
+visit_loop_todo_list(PARROT_INTERP, PMC *current, PMC *info)
+{
+ PMC **list_item;
+ List * const todo = (List *)PMC_data(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 ((list_item = (PMC **)Parrot_pmc_array_shift(interp, todo, enum_type_PMC))) {
+ current = *list_item;
+ 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 */
+ List *finish_list = (List *)PMC_data(PARROT_IMAGEIO(info)->id_list);
+ const INTVAL n = Parrot_pmc_array_length(interp, finish_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 = *(PMC**)Parrot_pmc_array_get(interp, finish_list, i, enum_type_PMC);
+ 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 */
More information about the parrot-commits
mailing list