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
|
45058
|
|
|
|
|
|
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
|
45058
|
|
|
|
|
|
symbols = mop_get_all_package_symbols(stash, TYPE_FILTER_CODE); |
17
|
45058
|
|
|
|
|
|
sv_2mortal((SV*)symbols); |
18
|
|
|
|
|
|
|
|
19
|
45058
|
|
|
|
|
|
(void)hv_iterinit(map); |
20
|
89031
|
100
|
|
|
|
|
while ((method = hv_iternextsv(map, &method_name, &method_name_len))) { |
21
|
|
|
|
|
|
|
SV *body; |
22
|
|
|
|
|
|
|
SV *stash_slot; |
23
|
|
|
|
|
|
|
|
24
|
43973
|
50
|
|
|
|
|
if (!SvROK(method)) { |
25
|
0
|
|
|
|
|
|
continue; |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
|
28
|
43973
|
100
|
|
|
|
|
if (sv_derived_from(method, "Class::MOP::Method")) { |
29
|
|
|
|
|
|
|
/* $method_object->body() */ |
30
|
43942
|
|
|
|
|
|
body = mop_call0(aTHX_ method, KEY_FOR(body)); |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
else { |
33
|
31
|
|
|
|
|
|
body = method; |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
43973
|
|
|
|
|
|
stash_slot = *hv_fetch(symbols, method_name, method_name_len, TRUE); |
37
|
43973
|
100
|
|
|
|
|
if (SvROK(stash_slot) && ((CV*)SvRV(body)) == ((CV*)SvRV(stash_slot))) { |
|
|
100
|
|
|
|
|
|
38
|
43968
|
|
|
|
|
|
continue; |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
/* delete $map->{$method_name} */ |
42
|
5
|
|
|
|
|
|
(void)hv_delete(map, method_name, method_name_len, G_DISCARD); |
43
|
|
|
|
|
|
|
} |
44
|
45058
|
|
|
|
|
|
} |
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
|
454468
|
|
|
|
|
|
HV *const obj = (HV *)SvRV(self); |
55
|
454468
|
|
|
|
|
|
SV *const class_name = HeVAL( hv_fetch_ent(obj, KEY_FOR(package), 0, HASH_FOR(package)) ); |
56
|
454468
|
|
|
|
|
|
HV *const stash = gv_stashsv(class_name, 0); |
57
|
|
|
|
|
|
|
UV current; |
58
|
|
|
|
|
|
|
SV *cache_flag; |
59
|
|
|
|
|
|
|
SV *map_ref; |
60
|
|
|
|
|
|
|
PPCODE: |
61
|
454468
|
100
|
|
|
|
|
if (!stash) { |
62
|
13
|
50
|
|
|
|
|
mXPUSHs(newRV_noinc((SV *)newHV())); |
63
|
13
|
|
|
|
|
|
return; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
454455
|
|
|
|
|
|
current = mop_check_package_cache_flag(aTHX_ stash); |
67
|
454455
|
|
|
|
|
|
cache_flag = HeVAL( hv_fetch_ent(obj, KEY_FOR(package_cache_flag), TRUE, HASH_FOR(package_cache_flag))); |
68
|
454455
|
|
|
|
|
|
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
|
454455
|
100
|
|
|
|
|
if ( !SvROK(map_ref) || SvTYPE(SvRV(map_ref)) != SVt_PVHV ) { |
|
|
50
|
|
|
|
|
|
72
|
4069
|
|
|
|
|
|
SV *new_map_ref = newRV_noinc((SV *)newHV()); |
73
|
4069
|
|
|
|
|
|
sv_2mortal(new_map_ref); |
74
|
4069
|
|
|
|
|
|
sv_setsv(map_ref, new_map_ref); |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
454455
|
100
|
|
|
|
|
if ( !SvOK(cache_flag) || SvUV(cache_flag) != current ) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
78
|
45058
|
|
|
|
|
|
mop_update_method_map(aTHX_ stash, (HV *)SvRV(map_ref)); |
79
|
45058
|
|
|
|
|
|
sv_setuv(cache_flag, mop_check_package_cache_flag(aTHX_ stash)); /* update_cache_flag() */ |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
454455
|
50
|
|
|
|
|
XPUSHs(map_ref); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
BOOT: |
85
|
463
|
|
|
|
|
|
mop_method_metaclass = newSVpvs("method_metaclass"); |
86
|
463
|
|
|
|
|
|
mop_associated_metaclass = newSVpvs("associated_metaclass"); |
87
|
463
|
|
|
|
|
|
mop_wrap = newSVpvs("wrap"); |
88
|
463
|
|
|
|
|
|
INSTALL_SIMPLE_READER(Mixin::HasMethods, method_metaclass); |
89
|
463
|
|
|
|
|
|
INSTALL_SIMPLE_READER(Mixin::HasMethods, wrapped_method_metaclass); |