3 #define ISA_CACHE "::LINEALIZED_ISA_CACHE::"
5 #ifdef no_mro_get_linear_isa
7 mouse_mro_get_linear_isa(pTHX_ HV* const stash){
8 GV* const cachegv = *(GV**)hv_fetchs(stash, ISA_CACHE, TRUE);
14 gv_init(cachegv, stash, ISA_CACHE, sizeof(ISA_CACHE)-1, TRUE);
20 if(SvIOK(gen) && SvIVX(gen) == (IV)mro_get_pkg_gen(stash)){
21 return isa; /* returns the cache if available */
28 get_linear_isa = get_cv("Mouse::Util::get_linear_isa", TRUE);
38 mXPUSHp(HvNAME_get(stash), HvNAMELEN_get(stash));
41 call_sv((SV*)get_linear_isa, G_SCALAR);
47 if(IsArrayRef(avref)){
48 AV* const av = (AV*)SvRV(avref);
49 I32 const len = AvFILLp(av) + 1;
52 for(i = 0; i < len; i++){
53 HV* const stash = gv_stashsv(AvARRAY(av)[i], FALSE);
55 av_push(isa, newSVpv(HvNAME(stash), 0));
60 Perl_croak(aTHX_ "Mouse:Util::get_linear_isa() didn't return an ARRAY reference");
67 sv_setiv(gen, (IV)mro_get_pkg_gen(stash));
70 #endif /* !no_mor_get_linear_isa */
74 mouse_av_at_safe(pTHX_ AV* const av, I32 const ix){
76 assert(SvTYPE(av) == SVt_PVAV);
77 assert(AvMAX(av) >= ix);
78 return &AvARRAY(av)[ix];
83 mouse_throw_error(SV* const metaobject, SV* const data /* not used */, const char* const fmt, ...){
88 PERL_UNUSED_ARG(data); /* for moose-compat */
94 message = vnewSVpvf(fmt, &args);
105 mPUSHs(newSVpvs("depth"));
110 call_method("throw_error", G_VOID);
111 croak("throw_error() did not throw the error (%"SVf")", message);
116 mouse_is_class_loaded(pTHX_ SV * const klass){
121 if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */
125 stash = gv_stashsv(klass, FALSE);
130 if (( gvp = (GV**)hv_fetchs(stash, "VERSION", FALSE) )) {
131 if(isGV(*gvp) && GvSV(*gvp) && SvOK(GvSV(*gvp))){
136 if (( gvp = (GV**)hv_fetchs(stash, "ISA", FALSE) )) {
137 if(isGV(*gvp) && GvAV(*gvp) && av_len(GvAV(*gvp)) != -1){
143 while(( he = hv_iternext(stash) )){
144 GV* const gv = (GV*)HeVAL(he);
160 mouse_call0 (pTHX_ SV *const self, SV *const method)
169 call_sv(method, G_SCALAR | G_METHOD);
179 mouse_call1 (pTHX_ SV *const self, SV *const method, SV* const arg1)
190 call_sv(method, G_SCALAR | G_METHOD);
200 mouse_mg_find(pTHX_ SV* const sv, const MGVTBL* const vtbl, I32 const flags){
204 for(mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic){
205 if(mg->mg_virtual == vtbl){
210 if(flags & MOUSEf_DIE_ON_FAIL){
211 croak("mouse_mg_find: no MAGIC found for %"SVf, sv_2mortal(newRV_inc(sv)));
216 MODULE = Mouse::Util PACKAGE = Mouse::Util
219 VERSIONCHECK: DISABLE
222 is_class_loaded(SV* sv)
225 get_code_info(CV* code)
230 if((gv = CvGV(code)) && isGV(gv) && (stash = GvSTASH(gv))){
232 mPUSHs(newSVpvn_share(HvNAME_get(stash), HvNAMELEN_get(stash), 0U));
233 mPUSHs(newSVpvn_share(GvNAME_get(gv), GvNAMELEN_get(gv), 0U));
237 get_code_package(CV* code)
241 if(CvGV(code) && isGV(CvGV(code)) && (stash = GvSTASH(CvGV(code)))){
242 RETVAL = newSVpvn_share(HvNAME_get(stash), HvNAMELEN_get(stash), 0U);
251 get_code_ref(SV* package, SV* name)
258 croak("You must define a package name");
261 croak("You must define a subroutine name");
264 stash = gv_stashsv(package, FALSE);
268 he = hv_fetch_ent(stash, name, FALSE, 0U);
270 GV* const gv = (GV*)hv_iterval(stash, he);
271 if(!isGV(gv)){ /* special constant or stub */
273 const char* const pv = SvPV_const(name, len);
274 gv_init(gv, stash, pv, len, GV_ADDMULTI);
290 generate_isa_predicate_for(SV* klass, SV* predicate_name = NULL)
293 const char* name_pv = NULL;
299 croak("You must define a class name");
303 SvGETMAGIC(predicate_name);
304 if(!SvOK(predicate_name)){
305 croak("You must define a predicate_name");
307 name_pv = SvPV_nolen_const(predicate_name);
310 xsub = mouse_generate_isa_predicate_for(aTHX_ klass, name_pv);
312 if(predicate_name == NULL){ /* anonymous predicate */
313 XPUSHs( newRV_noinc((SV*)xsub) );