4 mop_update_method_map(pTHX_ SV *const self, SV *const class_name, HV *const stash, HV *const map)
6 const char *const class_name_pv = HvNAME(stash); /* must be HvNAME(stash), not SvPV_nolen_const(class_name) */
7 SV *method_metaclass_name;
14 symbols = mop_get_all_package_symbols(stash, TYPE_FILTER_CODE);
15 sv_2mortal((SV*)symbols);
16 (void)hv_iterinit(symbols);
17 while ( (coderef = hv_iternextsv(symbols, &method_name, &method_name_len)) ) {
18 CV *cv = (CV *)SvRV(coderef);
24 if (!mop_get_code_info(coderef, &cvpkg_name, &cv_name)) {
28 /* this checks to see that the subroutine is actually from our package */
29 if ( !(strEQ(cvpkg_name, "constant") && strEQ(cv_name, "__ANON__")) ) {
30 if ( strNE(cvpkg_name, class_name_pv) ) {
35 method_slot = *hv_fetch(map, method_name, method_name_len, TRUE);
36 if ( SvOK(method_slot) ) {
37 SV *const body = mop_call0(aTHX_ method_slot, KEY_FOR(body)); /* $method_object->body() */
38 if ( SvROK(body) && ((CV *) SvRV(body)) == cv ) {
43 method_metaclass_name = mop_call0(aTHX_ self, mop_method_metaclass); /* $self->method_metaclass() */
46 $method_object = $method_metaclass->wrap(
48 associated_metaclass => $self,
49 package_name => $class_name,
58 PUSHs(method_metaclass_name); /* invocant */
59 mPUSHs(newRV_inc((SV *)cv));
60 PUSHs(mop_associated_metaclass);
62 PUSHs(KEY_FOR(package_name));
65 mPUSHs(newSVpv(method_name, method_name_len));
68 call_sv(mop_wrap, G_SCALAR | G_METHOD);
72 /* $map->{$method_name} = $method_object */
73 sv_setsv(method_slot, method_object);
80 MODULE = Class::MOP::Package PACKAGE = Class::MOP::Package
85 get_all_package_symbols(self, filter=TYPE_FILTER_NONE)
93 if ( ! SvROK(self) ) {
94 die("Cannot call get_all_package_symbols as a class method");
97 if (GIMME_V == G_VOID) {
103 if ( (he = hv_fetch_ent((HV *)SvRV(self), KEY_FOR(package), 0, HASH_FOR(package))) ) {
104 stash = gv_stashsv(HeVAL(he), 0);
112 symbols = mop_get_all_package_symbols(stash, filter);
113 PUSHs(sv_2mortal(newRV_noinc((SV *)symbols)));
119 HV *const obj = (HV *)SvRV(self);
120 SV *const class_name = HeVAL( hv_fetch_ent(obj, KEY_FOR(package), 0, HASH_FOR(package)) );
121 HV *const stash = gv_stashsv(class_name, 0);
127 mXPUSHs(newRV_noinc((SV *)newHV()));
131 current = mop_check_package_cache_flag(aTHX_ stash);
132 cache_flag = HeVAL( hv_fetch_ent(obj, KEY_FOR(package_cache_flag), TRUE, HASH_FOR(package_cache_flag)));
133 map_ref = HeVAL( hv_fetch_ent(obj, KEY_FOR(methods), TRUE, HASH_FOR(methods)));
135 /* $self->{methods} does not yet exist (or got deleted) */
136 if ( !SvROK(map_ref) || SvTYPE(SvRV(map_ref)) != SVt_PVHV ) {
137 SV *new_map_ref = newRV_noinc((SV *)newHV());
138 sv_2mortal(new_map_ref);
139 sv_setsv(map_ref, new_map_ref);
142 if ( !SvOK(cache_flag) || SvUV(cache_flag) != current ) {
143 mop_update_method_map(aTHX_ self, class_name, stash, (HV *)SvRV(map_ref));
144 sv_setuv(cache_flag, mop_check_package_cache_flag(aTHX_ stash)); /* update_cache_flag() */
150 INSTALL_SIMPLE_READER_WITH_KEY(Package, name, package);