/* NCI.pmc
 *  Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
 *  CVS Info
 *     $Id: nci.pmc,v 1.16 2003/08/28 13:17:01 leo Exp $
 *  Overview:
 *     The vtable functions for the native C call functions
 *  Data Structure and Algorithms:
 *  History:
 *     Initial revision by sean 2002/08/04
 *  Notes:
 *     Invoking a NCI function changes some registers according to pdd03.
 *     The caller has to preserve registers if needed.
 *  References:
 *     docs/pdds/pdd03_calling_conventions.pod
 */

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

pmclass NCI need_ext {

    void init() {
	SELF->cache.struct_val = NULL;
    }

    void set_string_keyed (PMC* func, STRING* value) {
	/* key = func_ptr, value = signature */
	SELF->cache.struct_val = (DPOINTER *)func;
	PMC_data(SELF) = build_call_func(INTERP, SELF, value);
    }

    void destroy() {
	if (PMC_data(SELF))
	    mem_sys_free(PMC_data(SELF));
    }

    void clone (PMC *ret) {
        ret->cache.struct_val = SELF->cache.struct_val;
	/* FIXME if data is malloced (JIT/i386!) then we need
	 * the length of data here, to memcpy it
	 * ManagedStruct or Buffer?
	 */
	PMC_data(ret) = PMC_data(SELF);
    }

    INTVAL defined () {
        return PMC_data(SELF) != NULL;
    }

    void* invoke (void * next) {
        Parrot_csub_t func = (Parrot_csub_t)D2FPTR(PMC_data(SELF));
        func(INTERP, SELF);
        return next;
    }
}
