| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include "mop.h" |
|
2
|
|
|
|
|
|
|
#include "ppport.h" |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
SV *mop_method_metaclass; |
|
5
|
|
|
|
|
|
|
SV *mop_associated_metaclass; |
|
6
|
|
|
|
|
|
|
SV *mop_wrap; |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
static void |
|
9
|
43955
|
|
|
|
|
|
mop_update_method_map(pTHX_ HV *const stash, HV *const map) |
|
10
|
|
|
|
|
|
|
{ |
|
11
|
|
|
|
|
|
|
char *method_name; |
|
12
|
|
|
|
|
|
|
I32 method_name_len; |
|
13
|
|
|
|
|
|
|
SV *method; |
|
14
|
|
|
|
|
|
|
HV *symbols; |
|
15
|
|
|
|
|
|
|
|
|
16
|
43955
|
|
|
|
|
|
symbols = mop_get_all_package_symbols(stash, TYPE_FILTER_CODE); |
|
17
|
43955
|
|
|
|
|
|
sv_2mortal((SV*)symbols); |
|
18
|
|
|
|
|
|
|
|
|
19
|
43955
|
|
|
|
|
|
(void)hv_iterinit(map); |
|
20
|
87287
|
100
|
|
|
|
|
while ((method = hv_iternextsv(map, &method_name, &method_name_len))) { |
|
21
|
|
|
|
|
|
|
SV *body; |
|
22
|
|
|
|
|
|
|
SV *stash_slot; |
|
23
|
|
|
|
|
|
|
|
|
24
|
43332
|
50
|
|
|
|
|
if (!SvROK(method)) { |
|
25
|
0
|
|
|
|
|
|
continue; |
|
26
|
|
|
|
|
|
|
} |
|
27
|
|
|
|
|
|
|
|
|
28
|
43332
|
100
|
|
|
|
|
if (sv_derived_from(method, "Class::MOP::Method")) { |
|
29
|
|
|
|
|
|
|
/* $method_object->body() */ |
|
30
|
43301
|
|
|
|
|
|
body = mop_call0(aTHX_ method, KEY_FOR(body)); |
|
31
|
|
|
|
|
|
|
} |
|
32
|
|
|
|
|
|
|
else { |
|
33
|
31
|
|
|
|
|
|
body = method; |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
43332
|
|
|
|
|
|
stash_slot = *hv_fetch(symbols, method_name, method_name_len, TRUE); |
|
37
|
43332
|
100
|
|
|
|
|
if (SvROK(stash_slot) && ((CV*)SvRV(body)) == ((CV*)SvRV(stash_slot))) { |
|
|
|
100
|
|
|
|
|
|
|
38
|
43327
|
|
|
|
|
|
continue; |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
/* delete $map->{$method_name} */ |
|
42
|
5
|
|
|
|
|
|
(void)hv_delete(map, method_name, method_name_len, G_DISCARD); |
|
43
|
|
|
|
|
|
|
} |
|
44
|
43955
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
MODULE = Class::MOP::Mixin::HasMethods PACKAGE = Class::MOP::Mixin::HasMethods |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
PROTOTYPES: DISABLE |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
void |
|
51
|
|
|
|
|
|
|
_method_map(self) |
|
52
|
|
|
|
|
|
|
SV *self |
|
53
|
|
|
|
|
|
|
PREINIT: |
|
54
|
444310
|
|
|
|
|
|
HV *const obj = (HV *)SvRV(self); |
|
55
|
444310
|
|
|
|
|
|
SV *const class_name = HeVAL( hv_fetch_ent(obj, KEY_FOR(package), 0, HASH_FOR(package)) ); |
|
56
|
444310
|
|
|
|
|
|
HV *const stash = gv_stashsv(class_name, 0); |
|
57
|
|
|
|
|
|
|
UV current; |
|
58
|
|
|
|
|
|
|
SV *cache_flag; |
|
59
|
|
|
|
|
|
|
SV *map_ref; |
|
60
|
|
|
|
|
|
|
PPCODE: |
|
61
|
444310
|
100
|
|
|
|
|
if (!stash) { |
|
62
|
13
|
50
|
|
|
|
|
mXPUSHs(newRV_noinc((SV *)newHV())); |
|
63
|
13
|
|
|
|
|
|
return; |
|
64
|
|
|
|
|
|
|
} |
|
65
|
|
|
|
|
|
|
|
|
66
|
444297
|
|
|
|
|
|
current = mop_check_package_cache_flag(aTHX_ stash); |
|
67
|
444297
|
|
|
|
|
|
cache_flag = HeVAL( hv_fetch_ent(obj, KEY_FOR(package_cache_flag), TRUE, HASH_FOR(package_cache_flag))); |
|
68
|
444297
|
|
|
|
|
|
map_ref = HeVAL( hv_fetch_ent(obj, KEY_FOR(methods), TRUE, HASH_FOR(methods))); |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
/* $self->{methods} does not yet exist (or got deleted) */ |
|
71
|
444297
|
100
|
|
|
|
|
if ( !SvROK(map_ref) || SvTYPE(SvRV(map_ref)) != SVt_PVHV ) { |
|
|
|
50
|
|
|
|
|
|
|
72
|
4001
|
|
|
|
|
|
SV *new_map_ref = newRV_noinc((SV *)newHV()); |
|
73
|
4001
|
|
|
|
|
|
sv_2mortal(new_map_ref); |
|
74
|
4001
|
|
|
|
|
|
sv_setsv(map_ref, new_map_ref); |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
|
|
77
|
444297
|
100
|
|
|
|
|
if ( !SvOK(cache_flag) || SvUV(cache_flag) != current ) { |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
78
|
43955
|
|
|
|
|
|
mop_update_method_map(aTHX_ stash, (HV *)SvRV(map_ref)); |
|
79
|
43955
|
|
|
|
|
|
sv_setuv(cache_flag, mop_check_package_cache_flag(aTHX_ stash)); /* update_cache_flag() */ |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
444297
|
50
|
|
|
|
|
XPUSHs(map_ref); |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
BOOT: |
|
85
|
451
|
|
|
|
|
|
mop_method_metaclass = newSVpvs("method_metaclass"); |
|
86
|
451
|
|
|
|
|
|
mop_associated_metaclass = newSVpvs("associated_metaclass"); |
|
87
|
451
|
|
|
|
|
|
mop_wrap = newSVpvs("wrap"); |
|
88
|
451
|
|
|
|
|
|
INSTALL_SIMPLE_READER(Mixin::HasMethods, method_metaclass); |
|
89
|
451
|
|
|
|
|
|
INSTALL_SIMPLE_READER(Mixin::HasMethods, wrapped_method_metaclass); |