/*
Copyright (C) 2001-2003, The Perl Foundation.
$Id: bound_nci.pmc 16275 2006-12-28 01:20:44Z particle $

=head1 NAME

src/pmc/bound_nci.pmc - Bound internal method

=head1 DESCRIPTION

A bound internal method is a NCI method call, where the object is
bound to this call instance.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"

pmclass Bound_NCI extends NCI need_ext {

/*

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

Bind the object C<obj> to this call instance.

=item C<PMC* get_pmc(void)>

Return the bound object.

=item C<void *invoke(void *next)>

Calls the associated C method, returning C<*next>.

=item C<void mark()>

Set the bound object live.

=cut

*/

    void set_pmc(PMC *obj) {
        PMC_pmc_val(SELF) = obj;
        if (!PMC_IS_NULL(obj))
            PObj_custom_mark_SET(SELF);
    }

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

    void* invoke(void * next) {
        if (PObj_get_FLAGS(SELF) & PObj_private0_FLAG) {
            /* bound multi sub
             * XXX maybe create separate PMC class
             * see also src/pmc/default.pmc:get_attr_str()
             * */
            PMC *multi = PMC_struct_val(SELF);
            next = VTABLE_invoke(INTERP, multi, next);
        }
        else {
            PMC *p2 = REG_PMC(2);
            INTERP->current_object = REG_PMC(2) = PMC_pmc_val(SELF);
            SUPER(next);
            REG_PMC(2) = p2;
        }
        return next;
    }

    void mark() {
        if (PMC_pmc_val(SELF))
            pobject_lives(INTERP, (PObj *)PMC_pmc_val(SELF));
        if (PObj_get_FLAGS(SELF) & PObj_private0_FLAG) {
            if (PMC_struct_val(SELF))
                pobject_lives(INTERP, (PObj *)PMC_struct_val(SELF));
        }
    }

}

/*

=back

=head1 SEE ALSO

F<src/pmc/nci.pmc>

=head1 HISTORY

Initial revision by leo 2005.01.31.

=cut

*/

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