/*
 * $Id: subproxy.pmc 46300 2010-05-05 03:58:50Z jimmy $
 * Copyright (C) 2003-2009, Parrot Foundation.
 */

/*
 * Sample SubProxy class
 *
 * s. src/dynpmc/main.pasm for usage
 */

/*
 * the real class enum is created at load time
 */
#define enum_class_SubProxy -1

pmclass SubProxy dynpmc extends Sub auto_attrs {

    VTABLE void init() {
        SUPER();
        PObj_get_FLAGS(SELF) |= PObj_private0_FLAG;
    }

    VTABLE void set_pmc(PMC *key) {
        PMC_data(SELF) = key;
    }

    VTABLE opcode_t* invoke(void* next) {
        if (PObj_get_FLAGS(SELF) & PObj_private0_FLAG) {

            PMC         *key = PMC_data_typed(SELF, PMC *);
            STRING      *file;
            PMC         *rsub_pmc, *sub_pmc;
            Parrot_Sub_attributes  *rsub,     *my_sub;

            if (!key)
                Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "SubProxy: no key");

            file = VTABLE_get_string(INTERP, key);
            if (!file)
                Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "SubProxy: no file");

            sub_pmc = key_next(INTERP, key);
            if (!sub_pmc)
                Parrot_ex_throw_from_c_args(INTERP, NULL, 1, "SubProxy: no sub");

            Parrot_load_bytecode(INTERP, file);
            rsub_pmc = VTABLE_get_pmc_keyed(INTERP,
                    INTERP->root_namespace, sub_pmc);

            if (!VTABLE_defined(INTERP, rsub_pmc))
                Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
                    "SubProxy: sub not found");

            PObj_get_FLAGS(SELF) &= ~PObj_private0_FLAG;
            PMC_get_sub(INTERP, SELF,     my_sub);
            PMC_get_sub(INTERP, rsub_pmc, rsub);
            my_sub->seg        = rsub->seg;
            my_sub->start_offs = rsub->start_offs;
            my_sub->end_offs   = rsub->end_offs;
        }
        return SUPER(next);
    }
}


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