/*
Copyright (C) 2006 The Perl Foundation.
$Id: stmref.pmc 17084 2007-02-20 20:03:37Z paultcochrane $

=head1 NAME

src/pmc/ref.pmc - Reference to a PMC

=head1 DESCRIPTION

The vtable functions for the Ref base class.

All methods not present below get a default body autogenerated inside
C<Parrot::Pmc2c>.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"
#include "parrot/stm/backend.h"

pmclass STMRef does ref is_shared need_ext {

/*

=item C<void init()>

Sets the referenced PMC to C<PMCNULL>.

=cut

*/

    void init() {
        SELF.init_pmc(PMCNULL);
    }

/*

=item C<void init_pmc(PMC *initializer)>

Sets the referenced PMC to C<initializer>.

=cut

*/

    void init_pmc(PMC* initializer) {
        PMC_struct_val(SELF) = Parrot_STM_alloc(INTERP, initializer);
        PObj_custom_mark_SET(SELF);
    }
/*

=item C<void mark()>

Marks the referenced PMC as live.

=cut

*/

    void mark() {
        Parrot_STM_mark_pmc_handle(INTERP, PMC_struct_val(SELF));
    }

/*

=item C<PMC* clone()>

Return ourself.

=cut

*/
    PMC* clone() {
        return SELF;
    }

/*

=back

This method must be implemented because they are not delegated.

=over 4

=item C<STRING *name()>

Returns the name of the PMC, not the name of the referenced PMC.

=cut

*/

    STRING* name() {
        return SUPER();
    }

    INTVAL defined() {
        Parrot_STM_PMC_handle handle = PMC_struct_val(pmc);
        PMC *value = Parrot_STM_read(INTERP, handle);
        return !PMC_IS_NULL(value);
    }

    void visit(visit_info *info) {
        /* so it's not delegated */
    }

    void freeze(visit_info *info) {
        IMAGE_IO * const io = info->image_io;

        SUPER(info);

        Parrot_freeze_STM_PMC_handle(INTERP, io, PMC_struct_val(SELF));
    }

    void thaw(visit_info *info) {
        IMAGE_IO * const io = info->image_io;

        SUPER(info);

        PMC_struct_val(SELF) =
            Parrot_thaw_STM_PMC_handle(INTERP, io);
    }

    void thawfinish(visit_info *info) {
        /* so it's not delegated */
    }

    PMC* get_pmc() {
        Parrot_STM_PMC_handle handle = PMC_struct_val(SELF);
        PMC *value = Parrot_STM_begin_update(INTERP, handle);
        return value;
    }
}

/*

=back

=head1 HISTORY

=cut

*/

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