/*
 * $Id: /mirror/trunk/languages/dotnet/pmc/dotnetmethodmetadata.pmc 29983 2008-08-02T22:45:13.271765Z allison  $
 * Copyright (C) 2006-2008, The Perl Foundation.
 */

/* .NET CLI Method Metadata PMC */


#include "parrot/extend.h"
#include "tableinfo.h"
#include "structures.h"


pmclass DotNetMethodMetadata dynpmc group dotnet {

    /* Instance initialization. We need a custom DOD marking and destroy. */
    void init()
    {
        PObj_custom_mark_SET(SELF);
        PObj_active_destroy_SET(SELF);
    }


    /* Get string vtable function; returns the name of the method. */
    STRING* get_string()
    {
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);

        /* Handle cases where we've an invalid PMC. */
        if (!m || !m->str_name)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetMethodMetadata PMC");

        return m->str_name;
    }


    /* Garbage Collection mark routine. */
    void mark()
    {
        /* Tell the GC about stuff we're holding on to. */
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);
        if (m)
        {
            if (m->parent)
                pobject_lives(INTERP, (PObj*)m->parent);
            if (m->str_name)
                pobject_lives(INTERP, (PObj*)m->str_name);
            if (m->params)
                pobject_lives(INTERP, (PObj*)m->params);
            if (m->bytecode)
                pobject_lives(INTERP, (PObj*)m->bytecode);
        }
    }


    /* Destructor. */
    void destroy()
    {
        /* Cleanup any memory we're using. */
        if (PMC_struct_val(SELF)) {
            mem_sys_free(PMC_struct_val(SELF));
            PMC_struct_val(SELF) = NULL;
        }
    }


    /* Get flags of the method. */
    METHOD INTVAL get_flags()
    {
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);
        INTVAL         result;

        /* Handle cases where we've an invalid PMC. */
        if (!m)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetMethodMetadata PMC");

        result = (INTVAL)m->flags;
        RETURN(INTVAL result);
    }


    /* Get implementation flags of the method. */
    METHOD INTVAL get_impl_flags()
    {
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);
        INTVAL         result;

        /* Handle cases where we've an invalid PMC. */
        if (!m)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetMethodMetadata PMC");

        result = (INTVAL)m->implFlags;
        RETURN(INTVAL result);
    }


    /* Get the position of the blob holding the signature for the method. */
    METHOD INTVAL get_signature()
    {
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);
        INTVAL         result;

        /* Handle cases where we've an invalid PMC. */
        if (!m)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetMethodMetadata PMC");

        result = (INTVAL)m->signature;
        RETURN(INTVAL result);
    }


    /* Get bytecode PMC for the method. */
    METHOD PMC* get_bytecode()
    {
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);
        PMC           *result;

        /* Handle cases where we've an invalid PMC. */
        if (!m || m->bytecode == NULL)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetMethodMetadata PMC");

        result = m->bytecode;
        RETURN(PMC *result);
    }


    /* Get parameters PMC array for the method. */
    METHOD PMC* get_params()
    {
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);
        PMC           *result;

        /* Handle cases where we've an invalid PMC. */
        if (!m || !m->params)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetMethodMetadata PMC");

        result = m->params;
        RETURN(PMC *result);
    }


    /* Get the class meta-data PMC for the method. */
    METHOD PMC* get_class()
    {
        dotnet_method *m = (dotnet_method *)PMC_struct_val(SELF);
        PMC           *result;

        /* Handle cases where we've an invalid PMC. */
        if (!m || !m->parent)
            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
               "Invalid DotNetMethodMetadata PMC");

        result = m->parent;
        RETURN(PMC *result);
    }
}


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