/*
 * $Id: /mirror/trunk/src/dynpmc/subproxy.pmc 30835 2008-09-06T04:01:15.986874Z chromatic  $
 * Copyright (C) 2003-2008, The Perl 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 need_ext extends Sub {

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

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

    opcode_t* invoke(void* next) {
        if (PObj_get_FLAGS(SELF) & PObj_private0_FLAG) {
            PMC *key = PMC_data_typed(SELF, PMC *);
            STRING *file;
            PMC *rsub, *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 = key_next(interp, key);
            if (!sub)
                Parrot_ex_throw_from_c_args(interp, NULL, 1, "SubProxy: no sub");

            Parrot_load_bytecode(interp, file);
            rsub = VTABLE_get_pmc_keyed(interp,
                    interp->root_namespace, sub);

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

            PObj_get_FLAGS(SELF) &= ~PObj_private0_FLAG;
            PMC_sub(SELF)->seg        = PMC_sub(rsub)->seg;
            PMC_sub(SELF)->start_offs = PMC_sub(rsub)->start_offs;
            PMC_sub(SELF)->end_offs   = PMC_sub(rsub)->end_offs;
        }
        return SUPER(next);
    }
}


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