Commit | Line | Data |
df6dd016 |
1 | #include "mouse.h" |
2 | |
3 | /* equivalent to "blessed($x) && $x->isa($klass)" */ |
4 | bool |
5 | mouse_is_instance_of(pTHX_ SV* const sv, SV* const klass){ |
6 | assert(sv); |
7 | assert(klass); |
8 | |
9 | if(IsObject(sv) && SvOK(klass)){ |
10 | bool ok; |
11 | |
12 | ENTER; |
13 | SAVETMPS; |
14 | |
15 | ok = SvTRUEx(mcall1s(sv, "isa", klass)); |
16 | |
17 | FREETMPS; |
18 | LEAVE; |
19 | |
20 | return ok; |
21 | } |
22 | |
23 | return FALSE; |
24 | } |
25 | |
26 | |
27 | bool |
28 | mouse_is_class_loaded(pTHX_ SV * const klass){ |
29 | HV *stash; |
30 | GV** gvp; |
31 | HE* he; |
32 | |
33 | if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */ |
34 | return FALSE; |
35 | } |
36 | |
37 | stash = gv_stashsv(klass, FALSE); |
38 | if (!stash) { |
39 | return FALSE; |
40 | } |
41 | |
42 | if (( gvp = (GV**)hv_fetchs(stash, "VERSION", FALSE) )) { |
43 | if(isGV(*gvp) && GvSV(*gvp) && SvOK(GvSV(*gvp))){ |
44 | return TRUE; |
45 | } |
46 | } |
47 | |
48 | if (( gvp = (GV**)hv_fetchs(stash, "ISA", FALSE) )) { |
49 | if(isGV(*gvp) && GvAV(*gvp) && av_len(GvAV(*gvp)) != -1){ |
50 | return TRUE; |
51 | } |
52 | } |
53 | |
54 | hv_iterinit(stash); |
55 | while(( he = hv_iternext(stash) )){ |
56 | GV* const gv = (GV*)HeVAL(he); |
57 | |
58 | if(isGV(gv)){ |
59 | if(GvCVu(gv)){ |
60 | return TRUE; |
61 | } |
62 | } |
63 | else if(SvOK(gv)){ |
64 | return TRUE; |
65 | } |
66 | } |
67 | return FALSE; |
68 | } |
69 | |
70 | |
71 | SV * |
72 | mouse_call0 (pTHX_ SV *const self, SV *const method) |
73 | { |
74 | dSP; |
75 | SV *ret; |
76 | |
77 | PUSHMARK(SP); |
78 | XPUSHs(self); |
79 | PUTBACK; |
80 | |
81 | call_sv(method, G_SCALAR | G_METHOD); |
82 | |
83 | SPAGAIN; |
84 | ret = POPs; |
85 | PUTBACK; |
86 | |
87 | return ret; |
88 | } |
89 | |
90 | SV * |
91 | mouse_call1 (pTHX_ SV *const self, SV *const method, SV* const arg1) |
92 | { |
93 | dSP; |
94 | SV *ret; |
95 | |
96 | PUSHMARK(SP); |
97 | EXTEND(SP, 2); |
98 | PUSHs(self); |
99 | PUSHs(arg1); |
100 | PUTBACK; |
101 | |
102 | call_sv(method, G_SCALAR | G_METHOD); |
103 | |
104 | SPAGAIN; |
105 | ret = POPs; |
106 | PUTBACK; |
107 | |
108 | return ret; |
109 | } |
110 | |
43165725 |
111 | MAGIC* |
112 | mouse_mg_find(pTHX_ SV* const sv, const MGVTBL* const vtbl, I32 const flags){ |
113 | MAGIC* mg; |
114 | |
115 | assert(sv != NULL); |
116 | for(mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic){ |
117 | if(mg->mg_virtual == vtbl){ |
118 | return mg; |
119 | } |
120 | } |
121 | |
122 | if(flags & MOUSEf_DIE_ON_FAIL){ |
123 | croak("mouse_mg_find: no MAGIC found for %"SVf, sv_2mortal(newRV_inc(sv))); |
124 | } |
125 | return NULL; |
126 | } |