/* Sub.pmc
 *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
 *  CVS Info
 *     $Id: sub.pmc,v 1.25 2003/08/28 08:11:05 leo Exp $
 *  Overview:
 *     These are the vtable functions for the Sub (subroutine) base class
 *  Data Structure and Algorithms:
 *  History:
 *     Initial version by Melvin on 2002/06/6
 *  Notes:
 *  References:
 */

#include "parrot/parrot.h"
#include "parrot/method_util.h"

pmclass Sub {

   void init () {
       PMC_sub(SELF) = new_sub(INTERP, sizeof(struct Parrot_Sub));
       SELF->cache.struct_val = NULL;
       PObj_custom_mark_destroy_SETALL(SELF);
   }

   void destroy () {
       struct Parrot_Sub * sub = (struct Parrot_Sub *)PMC_sub(SELF);
       mem_sys_free(sub);
   }

   void mark () {
        struct Parrot_Sub * sub = (struct Parrot_Sub *)PMC_sub(SELF);
        pobject_lives(INTERP, sub->ctx.warns);
   }

   void set_integer (PMC * value) {
       SELF->cache.struct_val = (void *)VTABLE_get_integer(INTERP, value);
   }

   void set_integer_native (INTVAL value) {
       SELF->cache.struct_val = (void *)value;
   }

   INTVAL get_integer () {
       return (INTVAL) SELF->cache.struct_val;
   }

   INTVAL defined () {
       return SELF->cache.struct_val != NULL;
   }

   void* invoke (void* next) {
	struct Parrot_Sub * sub = (struct Parrot_Sub *)PMC_sub(SELF);
	interpreter->ctx.warns = sub->ctx.warns;
	if (interpreter->code->cur_cs != sub->seg)
	     Parrot_switch_to_cs(interpreter, sub->seg);
	return SELF->cache.struct_val;
   }

   void clone (PMC *ret) {
       struct Parrot_Sub * sub;
       PObj_custom_mark_destroy_SETALL(ret);
       sub = PMC_sub(ret) = mem_sys_allocate(sizeof(struct Parrot_Sub));
       memcpy(sub, PMC_sub(SELF), sizeof(struct Parrot_Sub));
       buffer_mark_COW(sub->ctx.warns);
       ret->cache.struct_val = SELF->cache.struct_val;
   }

    void set_same (PMC* value) {
       SELF->cache.struct_val = value->cache.struct_val;

    }

    INTVAL is_equal (PMC* value) {
        return SELF->vtable == value->vtable &&
	       SELF->cache.struct_val == value->cache.struct_val;
    }

}
