[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