Commit | Line | Data |
d846ade3 |
1 | #include "mop.h" |
2 | |
3 | static bool |
4 | find_method (const char *key, STRLEN keylen, SV *val, void *ud) |
5 | { |
6 | bool *found_method = (bool *)ud; |
2dba318b |
7 | PERL_UNUSED_ARG(key); |
8 | PERL_UNUSED_ARG(keylen); |
9 | PERL_UNUSED_ARG(val); |
d846ade3 |
10 | *found_method = TRUE; |
11 | return FALSE; |
12 | } |
13 | |
4154c4d0 |
14 | static bool |
15 | check_version (SV *klass, SV *required_version) |
16 | { |
17 | bool ret = 0; |
18 | |
19 | dSP; |
20 | ENTER; |
21 | SAVETMPS; |
22 | PUSHMARK(SP); |
23 | EXTEND(SP, 2); |
24 | PUSHs(klass); |
25 | PUSHs(required_version); |
26 | PUTBACK; |
27 | |
28 | call_method("VERSION", G_DISCARD|G_VOID|G_EVAL); |
29 | |
30 | SPAGAIN; |
31 | |
32 | if (!SvTRUE(ERRSV)) { |
33 | ret = 1; |
34 | } |
35 | |
36 | PUTBACK; |
37 | FREETMPS; |
38 | LEAVE; |
39 | |
40 | return ret; |
41 | } |
42 | |
9b871d79 |
43 | EXTERN_C XS(boot_Class__MOP__Mixin__HasMethods); |
25bcd95c |
44 | EXTERN_C XS(boot_Class__MOP__Package); |
9b871d79 |
45 | EXTERN_C XS(boot_Class__MOP__Mixin__AttributeCore); |
25bcd95c |
46 | EXTERN_C XS(boot_Class__MOP__Method); |
47 | |
d846ade3 |
48 | MODULE = Class::MOP PACKAGE = Class::MOP |
49 | |
50 | PROTOTYPES: DISABLE |
51 | |
52 | BOOT: |
22932438 |
53 | mop_prehash_keys(); |
d846ade3 |
54 | |
9b871d79 |
55 | MOP_CALL_BOOT (boot_Class__MOP__Mixin__HasMethods); |
e3dcef7f |
56 | MOP_CALL_BOOT (boot_Class__MOP__Package); |
9b871d79 |
57 | MOP_CALL_BOOT (boot_Class__MOP__Mixin__AttributeCore); |
e3dcef7f |
58 | MOP_CALL_BOOT (boot_Class__MOP__Method); |
d846ade3 |
59 | |
60 | # use prototype here to be compatible with get_code_info from Sub::Identify |
61 | void |
62 | get_code_info(coderef) |
63 | SV *coderef |
64 | PROTOTYPE: $ |
65 | PREINIT: |
66 | char *pkg = NULL; |
67 | char *name = NULL; |
68 | PPCODE: |
704f58f9 |
69 | SvGETMAGIC(coderef); |
e1f52a8a |
70 | if (mop_get_code_info(coderef, &pkg, &name)) { |
d846ade3 |
71 | EXTEND(SP, 2); |
efc98200 |
72 | mPUSHs(newSVpv(pkg, 0)); |
73 | mPUSHs(newSVpv(name, 0)); |
d846ade3 |
74 | } |
75 | |
d846ade3 |
76 | void |
4154c4d0 |
77 | is_class_loaded(klass, options=NULL) |
d846ade3 |
78 | SV *klass |
4154c4d0 |
79 | HV *options |
d846ade3 |
80 | PREINIT: |
81 | HV *stash; |
82 | bool found_method = FALSE; |
83 | PPCODE: |
704f58f9 |
84 | SvGETMAGIC(klass); |
85 | if (!(SvPOKp(klass) && SvCUR(klass))) { /* XXX: SvPOK does not work with magical scalars */ |
d846ade3 |
86 | XSRETURN_NO; |
87 | } |
88 | |
89 | stash = gv_stashsv(klass, 0); |
90 | if (!stash) { |
91 | XSRETURN_NO; |
92 | } |
93 | |
4154c4d0 |
94 | if (options && hv_exists_ent(options, KEY_FOR(_version), HASH_FOR(_version))) { |
95 | HE *required_version = hv_fetch_ent(options, KEY_FOR(_version), 0, HASH_FOR(_version)); |
96 | if (check_version (klass, HeVAL(required_version))) { |
97 | XSRETURN_YES; |
98 | } |
99 | |
100 | XSRETURN_NO; |
101 | } |
102 | |
22932438 |
103 | if (hv_exists_ent (stash, KEY_FOR(VERSION), HASH_FOR(VERSION))) { |
104 | HE *version = hv_fetch_ent(stash, KEY_FOR(VERSION), 0, HASH_FOR(VERSION)); |
d846ade3 |
105 | SV *version_sv; |
106 | if (version && HeVAL(version) && (version_sv = GvSV(HeVAL(version)))) { |
107 | if (SvROK(version_sv)) { |
108 | SV *version_sv_ref = SvRV(version_sv); |
109 | |
110 | if (SvOK(version_sv_ref)) { |
111 | XSRETURN_YES; |
112 | } |
113 | } |
114 | else if (SvOK(version_sv)) { |
115 | XSRETURN_YES; |
116 | } |
117 | } |
118 | } |
119 | |
22932438 |
120 | if (hv_exists_ent (stash, KEY_FOR(ISA), HASH_FOR(ISA))) { |
121 | HE *isa = hv_fetch_ent(stash, KEY_FOR(ISA), 0, HASH_FOR(ISA)); |
d9d8a21b |
122 | if (isa && HeVAL(isa) && GvAV(HeVAL(isa)) && av_len(GvAV(HeVAL(isa))) != -1) { |
d846ade3 |
123 | XSRETURN_YES; |
124 | } |
125 | } |
126 | |
e1f52a8a |
127 | mop_get_package_symbols(stash, TYPE_FILTER_CODE, find_method, &found_method); |
d846ade3 |
128 | if (found_method) { |
129 | XSRETURN_YES; |
130 | } |
131 | |
132 | XSRETURN_NO; |