3 #define MY_CXT_KEY "Mouse::Util::_guts" XS_VERSION
9 #define ISA_CACHE "::LINEALIZED_ISA_CACHE::"
11 #ifdef no_mro_get_linear_isa
13 mouse_mro_get_linear_isa(pTHX_ HV* const stash){
14 GV* const cachegv = *(GV**)hv_fetchs(stash, ISA_CACHE, TRUE);
20 gv_init(cachegv, stash, ISA_CACHE, sizeof(ISA_CACHE)-1, TRUE);
26 if(SvIOK(gen) && SvIVX(gen) == (IV)mro_get_pkg_gen(stash)){
27 return isa; /* returns the cache if available */
31 GvAV(cachegv) = isa = newAV();
34 get_linear_isa = get_cv("Mouse::Util::get_linear_isa", TRUE);
44 mXPUSHp(HvNAME_get(stash), HvNAMELEN_get(stash));
47 call_sv((SV*)get_linear_isa, G_SCALAR);
53 if(IsArrayRef(avref)){
54 AV* const av = (AV*)SvRV(avref);
55 I32 const len = AvFILLp(av) + 1;
58 for(i = 0; i < len; i++){
59 HV* const stash = gv_stashsv(AvARRAY(av)[i], FALSE);
61 av_push(isa, newSVpv(HvNAME(stash), 0));
66 Perl_croak(aTHX_ "Mouse:Util::get_linear_isa() didn't return an ARRAY reference");
73 sv_setiv(gen, (IV)mro_get_pkg_gen(stash));
76 #endif /* !no_mor_get_linear_isa */
80 mouse_av_at_safe(pTHX_ AV* const av, I32 const ix){
82 assert(SvTYPE(av) == SVt_PVAV);
83 assert(AvMAX(av) >= ix);
84 return &AvARRAY(av)[ix];
89 mouse_throw_error(SV* const metaobject, SV* const data /* not used */, const char* const fmt, ...){
94 PERL_UNUSED_ARG(data); /* for moose-compat */
100 message = vnewSVpvf(fmt, &args);
111 mPUSHs(newSVpvs("depth"));
116 call_method("throw_error", G_VOID);
117 croak("throw_error() did not throw the error (%"SVf")", message);
122 mouse_is_class_loaded(pTHX_ SV * const klass){
127 if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */
131 stash = gv_stashsv(klass, FALSE);
136 if (( gvp = (GV**)hv_fetchs(stash, "VERSION", FALSE) )) {
137 if(isGV(*gvp) && GvSV(*gvp) && SvOK(GvSV(*gvp))){
142 if (( gvp = (GV**)hv_fetchs(stash, "ISA", FALSE) )) {
143 if(isGV(*gvp) && GvAV(*gvp) && av_len(GvAV(*gvp)) != -1){
149 while(( he = hv_iternext(stash) )){
150 GV* const gv = (GV*)HeVAL(he);
166 mouse_call0 (pTHX_ SV* const self, SV* const method) {
174 call_sv(method, G_SCALAR | G_METHOD);
184 mouse_call1 (pTHX_ SV* const self, SV* const method, SV* const arg1) {
194 call_sv(method, G_SCALAR | G_METHOD);
204 mouse_predicate_call(pTHX_ SV* const self, SV* const method) {
205 SV* const value = mcall0(self, method);
206 return SvTRUE(value);
210 mouse_get_metaclass(pTHX_ SV* metaclass_name){
214 assert(metaclass_name);
215 assert(MY_CXT.metas);
217 if(IsObject(metaclass_name)){
218 HV* const stash = SvSTASH(SvRV(metaclass_name));
220 metaclass_name = newSVpvn_share(HvNAME_get(stash), HvNAMELEN_get(stash), 0U);
221 sv_2mortal(metaclass_name);
224 he = hv_fetch_ent(MY_CXT.metas, metaclass_name, FALSE, 0U);
226 return he ? HeVAL(he) : &PL_sv_undef;
230 mouse_mg_find(pTHX_ SV* const sv, const MGVTBL* const vtbl, I32 const flags){
234 for(mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic){
235 if(mg->mg_virtual == vtbl){
240 if(flags & MOUSEf_DIE_ON_FAIL){
241 croak("mouse_mg_find: no MAGIC found for %"SVf, sv_2mortal(newRV_inc(sv)));
247 mouse_stash_fetch(pTHX_ HV* const stash, const char* const name, I32 const namelen, I32 const create) {
248 GV** const gvp = (GV**)hv_fetch(stash, name, namelen, create);
252 gv_init(*gvp, stash, name, namelen, GV_ADDMULTI);
261 MODULE = Mouse::Util PACKAGE = Mouse::Util
264 VERSIONCHECK: DISABLE
273 __register_metaclass_storage(HV* metas, bool cloning)
282 if(MY_CXT.metas) croak("Cannot set metaclass storage more than once");
283 MY_CXT.metas = metas;
284 SvREFCNT_inc_simple_void_NN(metas);
289 is_class_loaded(SV* sv)
292 get_code_info(CV* code)
297 if((gv = CvGV(code)) && isGV(gv) && (stash = GvSTASH(gv))){
299 mPUSHs(newSVpvn_share(HvNAME_get(stash), HvNAMELEN_get(stash), 0U));
300 mPUSHs(newSVpvn_share(GvNAME_get(gv), GvNAMELEN_get(gv), 0U));
304 get_code_package(CV* code)
308 if(CvGV(code) && isGV(CvGV(code)) && (stash = GvSTASH(CvGV(code)))){
309 RETVAL = newSVpvn_share(HvNAME_get(stash), HvNAMELEN_get(stash), 0U);
318 get_code_ref(SV* package, SV* name)
327 croak("You must define a package name");
330 croak("You must define a subroutine name");
333 stash = gv_stashsv(package, FALSE);
338 name_pv = SvPV_const(name, name_len);
339 gv = stash_fetch(stash, name_pv, name_len, FALSE);
340 RETVAL = gv ? GvCVu(gv) : NULL;
350 generate_isa_predicate_for(SV* arg, SV* predicate_name = NULL)
352 generate_isa_predicate_for = 0
353 generate_can_predicate_for = 1
356 const char* name_pv = NULL;
362 croak("You must define %s", ix == 0 ? "a class name" : "method names");
366 SvGETMAGIC(predicate_name);
367 if(!SvOK(predicate_name)){
368 croak("You must define %s", "a predicate name");
370 name_pv = SvPV_nolen_const(predicate_name);
374 xsub = mouse_generate_isa_predicate_for(aTHX_ arg, name_pv);
377 xsub = mouse_generate_can_predicate_for(aTHX_ arg, name_pv);
380 if(predicate_name == NULL){ /* anonymous predicate */
381 XPUSHs( newRV_noinc((SV*)xsub) );