/*
Copyright (C) 2001-2008, The Perl Foundation.
$Id: /mirror/trunk/src/pmc/ref.pmc 28287 2008-06-12T19:34:51.229254Z Whiteknight  $

=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"

pmclass Ref provides ref {

/*

=item C<void init()>

Sets the referenced PMC to C<PMCNULL>.

=cut

*/

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

    VTABLE void destroy() {
        SELF.init_pmc(NULL);
        /* don't pass it on */
    }

/*

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

Sets the referenced PMC to C<initializer>.

=cut

*/

    VTABLE void init_pmc(PMC *initializer) {
        /* the referred PMC itself */
        PMC_pmc_val(SELF) = initializer;
        PObj_custom_mark_SET(SELF);

        /* if referred PMC needs active destruction we have to pass it on */
        if (initializer && PObj_active_destroy_TEST(initializer))
            PObj_active_destroy_SET(SELF);
    }

/*

=item C<void set_pmc(PMC *other)>

Sets the referenced PMC to C<*other>.

=item C<PMC *get_pmc()>

Get the referenced PMC.

=cut

*/

    VTABLE void set_pmc(PMC *other) {
        PObj_active_destroy_CLEAR(SELF);
        GC_WRITE_BARRIER(INTERP, SELF, PMC_pmc_val(SELF), other);
        SELF.init_pmc(other);
    }

    VTABLE void assign_pmc(PMC *other) {
        SELF.set_pmc(other);
    }

    VTABLE PMC *get_pmc() {
        return PMC_pmc_val(SELF);
    }

/*

=item C<INTVAL type()>

Returns the PMC's type.

=cut

*/

    VTABLE INTVAL type() {
        return VTABLE_type(interp, PMC_pmc_val(SELF));
    }

/*

=item C<void mark()>

Marks the referenced PMC as live.

=cut

*/

    VTABLE void mark() {
        pobject_lives(INTERP, (PObj *)PMC_pmc_val(SELF));
    }

/*

=back

These two methods 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

*/

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

/*

=item C<void morph(INTVAL type)>

Changes the PMC to a PMC of a new type.

=cut

*/
    VTABLE void morph(INTVAL type) {
        SUPER(type);
    }

}

/*

=back

=head1 HISTORY

Initial revision by leo 2003.09.01.

Allowed null value by TOGoS 2004.07.28 (evil+bad?)

=cut

*/

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