Commit | Line | Data |
d846ade3 |
1 | #include "mop.h" |
2 | |
7ec7b950 |
3 | SV *mop_method_metaclass; |
4 | SV *mop_associated_metaclass; |
daf9799b |
5 | SV *mop_associated_attribute; |
7ec7b950 |
6 | SV *mop_wrap; |
1bc0cb6b |
7 | SV *mop_methods; |
8 | SV *mop_name; |
9 | SV *mop_body; |
10 | SV *mop_package; |
11 | SV *mop_package_name; |
12 | SV *mop_package_cache_flag; |
87cfe982 |
13 | SV *mop_initialize; |
14 | SV *mop_isa; |
15 | SV *mop_can; |
16 | SV *mop_Class; |
1bc0cb6b |
17 | SV *mop_VERSION; |
18 | SV *mop_ISA; |
7ec7b950 |
19 | |
00370481 |
20 | /* equivalent to "blessed($x) && $x->isa($klass)" */ |
21 | bool |
22 | mop_is_instance_of(pTHX_ SV* const sv, SV* const klass){ |
23 | assert(sv); |
24 | assert(klass); |
25 | |
26 | if(SvROK(sv) && SvOBJECT(SvRV(sv)) && SvOK(klass)){ |
27 | bool ok; |
28 | |
29 | ENTER; |
30 | SAVETMPS; |
31 | |
32 | ok = SvTRUEx(mop_call1(aTHX_ sv, mop_isa, klass)); |
33 | |
34 | FREETMPS; |
35 | LEAVE; |
36 | |
e192207e |
37 | return ok; |
00370481 |
38 | } |
39 | |
40 | return FALSE; |
41 | } |
eaca1141 |
42 | |
d846ade3 |
43 | static bool |
44 | find_method (const char *key, STRLEN keylen, SV *val, void *ud) |
45 | { |
eaca1141 |
46 | bool * const found_method = (bool *)ud; |
2dba318b |
47 | PERL_UNUSED_ARG(key); |
48 | PERL_UNUSED_ARG(keylen); |
49 | PERL_UNUSED_ARG(val); |
d846ade3 |
50 | *found_method = TRUE; |
51 | return FALSE; |
52 | } |
53 | |
eaca1141 |
54 | |
55 | bool |
56 | mop_is_class_loaded(pTHX_ SV * const klass){ |
57 | HV *stash; |
2a30c752 |
58 | HE* he; |
eaca1141 |
59 | |
60 | if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */ |
61 | return FALSE; |
62 | } |
63 | |
64 | stash = gv_stashsv(klass, 0); |
65 | if (!stash) { |
66 | return FALSE; |
67 | } |
68 | |
2a30c752 |
69 | if (( he = hv_fetch_ent (stash, mop_VERSION, FALSE, 0U) )) { |
70 | GV* const version_gv = (GV*)HeVAL(he); |
71 | if(isGV(version_gv) && GvSV(version_gv) && SvOK(GvSV(version_gv))){ |
72 | return TRUE; |
eaca1141 |
73 | } |
74 | } |
75 | |
2a30c752 |
76 | if (( he = hv_fetch_ent (stash, mop_ISA, FALSE, 0U) )) { |
77 | GV* const isa_gv = (GV*)HeVAL(he); |
78 | if(isGV(isa_gv) && GvAV(isa_gv) && av_len(GvAV(isa_gv)) != -1){ |
79 | return TRUE; |
eaca1141 |
80 | } |
81 | } |
82 | |
83 | { |
84 | bool found_method = FALSE; |
85 | mop_get_package_symbols(stash, TYPE_FILTER_CODE, find_method, &found_method); |
2a30c752 |
86 | return found_method; |
eaca1141 |
87 | } |
88 | } |
89 | |
d846ade3 |
90 | MODULE = Class::MOP PACKAGE = Class::MOP |
91 | |
92 | PROTOTYPES: DISABLE |
93 | |
94 | BOOT: |
1bc0cb6b |
95 | mop_method_metaclass = MAKE_KEYSV(method_metaclass); |
1bc0cb6b |
96 | mop_associated_metaclass = MAKE_KEYSV(associated_metaclass); |
daf9799b |
97 | mop_associated_attribute = MAKE_KEYSV(associated_attribute); |
98 | mop_wrap = MAKE_KEYSV(wrap); |
1bc0cb6b |
99 | mop_methods = MAKE_KEYSV(methods); |
100 | mop_name = MAKE_KEYSV(name); |
101 | mop_body = MAKE_KEYSV(body); |
102 | mop_package = MAKE_KEYSV(package); |
103 | mop_package_name = MAKE_KEYSV(package_name); |
104 | mop_package_cache_flag = MAKE_KEYSV(_package_cache_flag); |
87cfe982 |
105 | mop_initialize = MAKE_KEYSV(initialize); |
106 | mop_Class = MAKE_KEYSV(Class::MOP::Class); |
1bc0cb6b |
107 | mop_VERSION = MAKE_KEYSV(VERSION); |
108 | mop_ISA = MAKE_KEYSV(ISA); |
00370481 |
109 | mop_isa = MAKE_KEYSV(isa); |
87cfe982 |
110 | mop_can = MAKE_KEYSV(can); |
d846ade3 |
111 | |
c79ae27a |
112 | MOP_CALL_BOOT( Class__MOP__Package ); |
113 | MOP_CALL_BOOT( Class__MOP__Class ); |
114 | MOP_CALL_BOOT( Class__MOP__Attribute ); |
115 | MOP_CALL_BOOT( Class__MOP__Instance ); |
116 | MOP_CALL_BOOT( Class__MOP__Method ); |
117 | MOP_CALL_BOOT( Class__MOP__Method__Accessor ); |
118 | MOP_CALL_BOOT( Class__MOP__Method__Constructor ); |
d846ade3 |
119 | |
120 | # use prototype here to be compatible with get_code_info from Sub::Identify |
121 | void |
122 | get_code_info(coderef) |
123 | SV *coderef |
124 | PROTOTYPE: $ |
125 | PREINIT: |
126 | char *pkg = NULL; |
127 | char *name = NULL; |
128 | PPCODE: |
704f58f9 |
129 | SvGETMAGIC(coderef); |
e1f52a8a |
130 | if (mop_get_code_info(coderef, &pkg, &name)) { |
d846ade3 |
131 | EXTEND(SP, 2); |
efc98200 |
132 | mPUSHs(newSVpv(pkg, 0)); |
133 | mPUSHs(newSVpv(name, 0)); |
d846ade3 |
134 | } |
135 | |
d846ade3 |
136 | |
eaca1141 |
137 | bool |
138 | is_class_loaded(SV* klass = &PL_sv_undef) |
139 | INIT: |
140 | SvGETMAGIC(klass); |
d846ade3 |
141 | |
00370481 |
142 | |
143 | |
144 | #bool |
145 | #is_instance_of(SV* sv, SV* klass) |
146 | #INIT: |
147 | # SvGETMAGIC(sv); |
148 | # SvGETMAGIC(klass); |
149 | # |