/*
Copyright (C) 2001-2010, Parrot Foundation.
$Id: packfilefixuptable.pmc 46300 2010-05-05 03:58:50Z jimmy $

=head1 NAME

src/pmc/packfilefixuptable.pmc - PackfileFixupTable PMC

=head1 DESCRIPTION

This class implements a PackfileFixupTable object, a segment of the .pbc
data file storing an array of PackfileFixupEntry PMCs.

See packfile.pmc for the toplevel Packfile interface, see packfilesegment.pmc
for the list of common methods every packfile segment pmc must implement; see
PDD13 for the design spec.


=head2 Methods

=over 4

=cut

*/

/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */

pmclass PackfileFixupTable auto_attrs extends PackfileSegment {
    /* RPA of entries */
    ATTR PMC *entries;

/*

=item C<init>

Create empty PackfileFixupTable.

=cut

*/

    VTABLE void init() {
        Parrot_PackfileFixupTable_attributes * attrs =
                PMC_data_typed(SELF, Parrot_PackfileFixupTable_attributes*);

        attrs->entries = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);

        PObj_custom_mark_SET(SELF);
    }

/*

=item C<void mark()>

Marks the object as live.

=cut

*/

    VTABLE void mark() {
        Parrot_PackfileFixupTable_attributes * attrs =
                PARROT_PACKFILEFIXUPTABLE(SELF);

        Parrot_gc_mark_PMC_alive(INTERP, attrs->entries);

        SUPER();
    }

/*

=item C<void set_pointer(void *pointer)>

Initialize from PackFile_FixupTable pointer.

=cut

*/

    VTABLE void set_pointer(void * pointer) {
        Parrot_PackfileFixupTable_attributes * attrs =
                PARROT_PACKFILEFIXUPTABLE(SELF);
        PackFile_FixupTable * table = (PackFile_FixupTable*)pointer;

        PMC                 *entry;
        PackFile_FixupEntry *val;
        opcode_t             i;

        VTABLE_set_integer_native(INTERP, attrs->entries, table->fixup_count);

        for (i = 0; i < table->fixup_count; ++i) {
            val = table->fixups + i;
            entry = Parrot_pmc_new(INTERP, enum_class_PackfileFixupEntry);
            VTABLE_set_pointer(INTERP, entry, (void*)val);
            VTABLE_set_pmc_keyed_int(INTERP, attrs->entries, i, entry);
        }
    }

/*

=item C<void *get_pointer()>

Create PackFile_FixupTable* from self.

=cut

*/
    VTABLE void *get_pointer() {
        Parrot_PackfileFixupTable_attributes * attrs =
                PARROT_PACKFILEFIXUPTABLE(SELF);
        PackFile_FixupTable * pftable =
                mem_gc_allocate_zeroed_typed(INTERP, PackFile_FixupTable);
        PMC                 * entry;
        PackFile_FixupEntry * val;
        opcode_t              i;

        pftable->base.type   = PF_FIXUP_SEG;
        pftable->fixup_count = VTABLE_elements(INTERP, attrs->entries);
        pftable->fixups      = mem_gc_allocate_n_typed(INTERP,
                pftable->fixup_count, PackFile_FixupEntry);

        /* Copy all entries */
        for (i = 0; i < pftable->fixup_count; ++i) {
            entry = VTABLE_get_pmc_keyed_int(INTERP, attrs->entries, i);
            val   = (PackFile_FixupEntry*)VTABLE_get_pointer(INTERP, entry);
            pftable->fixups[i] = *val;
            mem_gc_free(INTERP, val);
        }

        return pftable;
    }


/*

=item C<INTVAL elements()>

Get the number of elements in the array.

=cut

*/
    VTABLE INTVAL elements() {
        return VTABLE_elements(INTERP,
                PARROT_PACKFILEFIXUPTABLE(SELF)->entries);
    }


/*

=item C<PMC *get_pmc_keyed_int(INTVAL index)>

Fetch the given PackfileFixupEntry PMC.

=cut

*/
    VTABLE PMC *get_pmc_keyed_int(INTVAL index)  {
        return VTABLE_get_pmc_keyed_int(INTERP,
            PARROT_PACKFILEFIXUPTABLE(SELF)->entries, index);
    }


/*

=item C<void set_pmc_keyed_int(INTVAL index, PMC *value)>

Store a PackfileFixupEntry PMC to the given slot.

=cut

*/
    VTABLE void set_pmc_keyed_int(INTVAL index, PMC *value)  {
        VTABLE_set_pmc_keyed_int(INTERP,
                PARROT_PACKFILEFIXUPTABLE(SELF)->entries, index, value);
    }


/*

=item C<METHOD type()>

Set segment type.

=cut

*/

    METHOD type() {
        RETURN(INTVAL PF_FIXUP_SEG);
    }

}
/*

=back

=cut

*/

/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
