From: gfx Date: Mon, 3 Aug 2009 08:26:40 +0000 (+0900) Subject: Merge master into topic/xs-attr-template X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a1b4c30061aad686dc8c912303551bf891e78263;p=gitmo%2FClass-MOP.git Merge master into topic/xs-attr-template --- a1b4c30061aad686dc8c912303551bf891e78263 diff --cc lib/Class/MOP/Class.pm index 7fb3622,400ddd3..c7c3005 --- a/lib/Class/MOP/Class.pm +++ b/lib/Class/MOP/Class.pm @@@ -337,15 -341,13 +341,13 @@@ sub create # all these attribute readers will be bootstrapped # away in the Class::MOP bootstrap section -sub get_attribute_map { $_[0]->{'attributes'} } -sub attribute_metaclass { $_[0]->{'attribute_metaclass'} } -sub instance_metaclass { $_[0]->{'instance_metaclass'} } -sub immutable_trait { $_[0]->{'immutable_trait'} } -sub constructor_class { $_[0]->{'constructor_class'} } -sub constructor_name { $_[0]->{'constructor_name'} } -sub destructor_class { $_[0]->{'destructor_class'} } +#sub get_attribute_map { $_[0]->{'attributes'} } +#sub attribute_metaclass { $_[0]->{'attribute_metaclass'} } - #sub method_metaclass { $_[0]->{'method_metaclass'} } - #sub wrapped_method_metaclass { $_[0]->{'wrapped_method_metaclass'} } +#sub instance_metaclass { $_[0]->{'instance_metaclass'} } +#sub immutable_trait { $_[0]->{'immutable_trait'} } +#sub constructor_class { $_[0]->{'constructor_class'} } +#sub constructor_name { $_[0]->{'constructor_name'} } +#sub destructor_class { $_[0]->{'destructor_class'} } # Instance Construction & Cloning diff --cc lib/Class/MOP/Package.pm index 0336a57,5da609f..1a29698 --- a/lib/Class/MOP/Package.pm +++ b/lib/Class/MOP/Package.pm @@@ -90,6 -99,11 +99,11 @@@ sub namespace \%{$_[0]->{'package'} . '::'} } -sub method_metaclass { $_[0]->{'method_metaclass'} } -sub wrapped_method_metaclass { $_[0]->{'wrapped_method_metaclass'} } ++#sub method_metaclass { $_[0]->{'method_metaclass'} } ++#sub wrapped_method_metaclass { $_[0]->{'wrapped_method_metaclass'} } + + sub _method_map { $_[0]->{'methods'} } + # utility methods { diff --cc xs/Class.xs index d779683,0000000..e84eae4 mode 100644,000000..100644 --- a/xs/Class.xs +++ b/xs/Class.xs @@@ -1,129 -1,0 +1,16 @@@ +#include "mop.h" + - static void - mop_update_method_map(pTHX_ SV *const self, SV *const class_name, HV *const stash, HV *const map) - { - const char *const class_name_pv = HvNAME(stash); /* must be HvNAME(stash), not SvPV_nolen_const(class_name) */ - SV *method_metaclass_name; - char *method_name; - I32 method_name_len; - SV *coderef; - HV *symbols; - dSP; - - symbols = mop_get_all_package_symbols(stash, TYPE_FILTER_CODE); - sv_2mortal((SV*)symbols); - (void)hv_iterinit(symbols); - while ( (coderef = hv_iternextsv(symbols, &method_name, &method_name_len)) ) { - CV *cv = (CV *)SvRV(coderef); - char *cvpkg_name; - char *cv_name; - SV *method_slot; - SV *method_object; - - if (!mop_get_code_info(coderef, &cvpkg_name, &cv_name)) { - continue; - } - - /* this checks to see that the subroutine is actually from our package */ - if ( !(strEQ(cvpkg_name, "constant") && strEQ(cv_name, "__ANON__")) ) { - if ( strNE(cvpkg_name, class_name_pv) ) { - continue; - } - } - - method_slot = *hv_fetch(map, method_name, method_name_len, TRUE); - if ( SvOK(method_slot) ) { - SV *const body = mop_call0(aTHX_ method_slot, mop_body); /* $method_object->body() */ - if ( SvROK(body) && ((CV *) SvRV(body)) == cv ) { - continue; - } - } - - method_metaclass_name = mop_call0(aTHX_ self, mop_method_metaclass); /* $self->method_metaclass() */ - - /* - $method_object = $method_metaclass->wrap( - $cv, - associated_metaclass => $self, - package_name => $class_name, - name => $method_name - ); - */ - ENTER; - SAVETMPS; - - PUSHMARK(SP); - EXTEND(SP, 8); - PUSHs(method_metaclass_name); /* invocant */ - mPUSHs(newRV_inc((SV *)cv)); - PUSHs(mop_associated_metaclass); - PUSHs(self); - PUSHs(mop_package_name); - PUSHs(class_name); - PUSHs(mop_name); - mPUSHs(newSVpv(method_name, method_name_len)); - PUTBACK; - - call_sv(mop_wrap, G_SCALAR | G_METHOD); - SPAGAIN; - method_object = POPs; - PUTBACK; - /* $map->{$method_name} = $method_object */ - sv_setsv(method_slot, method_object); - - FREETMPS; - LEAVE; - } - } + +MODULE = Class::MOP::Class PACKAGE = Class::MOP::Class + +BOOT: + INSTALL_SIMPLE_READER_WITH_KEY(Class, get_attribute_map, attributes); - /* INSTALL_SIMPLE_READER_WITH_KEY(Class, _method_map, methods); */ + INSTALL_SIMPLE_READER(Class, attribute_metaclass); - INSTALL_SIMPLE_READER(Class, method_metaclass); - INSTALL_SIMPLE_READER(Class, wrapped_method_metaclass); + INSTALL_SIMPLE_READER(Class, instance_metaclass); + INSTALL_SIMPLE_READER(Class, immutable_trait); + INSTALL_SIMPLE_READER(Class, constructor_name); + INSTALL_SIMPLE_READER(Class, constructor_class); + INSTALL_SIMPLE_READER(Class, destructor_class); + + +PROTOTYPES: DISABLE - - void - get_method_map(self) - SV *self - PREINIT: - HV *const obj = (HV *)SvRV(self); - SV *const class_name = HeVAL( hv_fetch_ent(obj, mop_package, 0, 0U) ); - HV *const stash = gv_stashsv(class_name, 0); - UV current; - SV *cache_flag; - SV *map_ref; - PPCODE: - if (!stash) { - mXPUSHs(newRV_noinc((SV *)newHV())); - return; - } - - current = mop_check_package_cache_flag(aTHX_ stash); - cache_flag = HeVAL( hv_fetch_ent(obj, mop_package_cache_flag, TRUE, 0U)); - map_ref = HeVAL( hv_fetch_ent(obj, mop_methods, TRUE, 0U)); - - /* $self->{methods} does not yet exist (or got deleted) */ - if ( !SvROK(map_ref) || SvTYPE(SvRV(map_ref)) != SVt_PVHV ) { - SV *new_map_ref = newRV_noinc((SV *)newHV()); - sv_2mortal(new_map_ref); - sv_setsv(map_ref, new_map_ref); - } - - if ( !SvOK(cache_flag) || SvUV(cache_flag) != current ) { - mop_update_method_map(aTHX_ self, class_name, stash, (HV *)SvRV(map_ref)); - sv_setuv(cache_flag, mop_check_package_cache_flag(aTHX_ stash)); /* update_cache_flag() */ - } - - XPUSHs(map_ref); diff --cc xs/Package.xs index 79d92a2,362c407..d6ac749 --- a/xs/Package.xs +++ b/xs/Package.xs @@@ -1,5 -1,82 +1,82 @@@ #include "mop.h" + static void + mop_update_method_map(pTHX_ SV *const self, SV *const class_name, HV *const stash, HV *const map) + { + const char *const class_name_pv = HvNAME(stash); /* must be HvNAME(stash), not SvPV_nolen_const(class_name) */ + SV *method_metaclass_name; + char *method_name; + I32 method_name_len; + SV *coderef; + HV *symbols; + dSP; + + symbols = mop_get_all_package_symbols(stash, TYPE_FILTER_CODE); + sv_2mortal((SV*)symbols); + (void)hv_iterinit(symbols); + while ( (coderef = hv_iternextsv(symbols, &method_name, &method_name_len)) ) { + CV *cv = (CV *)SvRV(coderef); + char *cvpkg_name; + char *cv_name; + SV *method_slot; + SV *method_object; + + if (!mop_get_code_info(coderef, &cvpkg_name, &cv_name)) { + continue; + } + + /* this checks to see that the subroutine is actually from our package */ + if ( !(strEQ(cvpkg_name, "constant") && strEQ(cv_name, "__ANON__")) ) { + if ( strNE(cvpkg_name, class_name_pv) ) { + continue; + } + } + + method_slot = *hv_fetch(map, method_name, method_name_len, TRUE); + if ( SvOK(method_slot) ) { - SV *const body = mop_call0(aTHX_ method_slot, KEY_FOR(body)); /* $method_object->body() */ ++ SV *const body = mop_call0(aTHX_ method_slot, mop_body); /* $method_object->body() */ + if ( SvROK(body) && ((CV *) SvRV(body)) == cv ) { + continue; + } + } + + method_metaclass_name = mop_call0(aTHX_ self, mop_method_metaclass); /* $self->method_metaclass() */ + + /* + $method_object = $method_metaclass->wrap( + $cv, + associated_metaclass => $self, + package_name => $class_name, + name => $method_name + ); + */ + ENTER; + SAVETMPS; + + PUSHMARK(SP); + EXTEND(SP, 8); + PUSHs(method_metaclass_name); /* invocant */ + mPUSHs(newRV_inc((SV *)cv)); + PUSHs(mop_associated_metaclass); + PUSHs(self); - PUSHs(KEY_FOR(package_name)); ++ PUSHs(mop_package_name); + PUSHs(class_name); - PUSHs(KEY_FOR(name)); ++ PUSHs(mop_name); + mPUSHs(newSVpv(method_name, method_name_len)); + PUTBACK; + + call_sv(mop_wrap, G_SCALAR | G_METHOD); + SPAGAIN; + method_object = POPs; + PUTBACK; + /* $map->{$method_name} = $method_object */ + sv_setsv(method_slot, method_object); + + FREETMPS; + LEAVE; + } + } + MODULE = Class::MOP::Package PACKAGE = Class::MOP::Package PROTOTYPES: DISABLE @@@ -35,5 -112,39 +112,42 @@@ get_all_package_symbols(self, filter=TY symbols = mop_get_all_package_symbols(stash, filter); PUSHs(sv_2mortal(newRV_noinc((SV *)symbols))); + void + get_method_map(self) + SV *self + PREINIT: + HV *const obj = (HV *)SvRV(self); - SV *const class_name = HeVAL( hv_fetch_ent(obj, KEY_FOR(package), 0, HASH_FOR(package)) ); ++ SV *const class_name = HeVAL( hv_fetch_ent(obj, mop_package, 0, 0U) ); + HV *const stash = gv_stashsv(class_name, 0); + UV current; + SV *cache_flag; + SV *map_ref; + PPCODE: + if (!stash) { + mXPUSHs(newRV_noinc((SV *)newHV())); + return; + } + + current = mop_check_package_cache_flag(aTHX_ stash); - cache_flag = HeVAL( hv_fetch_ent(obj, KEY_FOR(package_cache_flag), TRUE, HASH_FOR(package_cache_flag))); - map_ref = HeVAL( hv_fetch_ent(obj, KEY_FOR(methods), TRUE, HASH_FOR(methods))); ++ cache_flag = HeVAL( hv_fetch_ent(obj, mop_package_cache_flag, TRUE, 0U)); ++ map_ref = HeVAL( hv_fetch_ent(obj, mop_methods, TRUE, 0U)); + + /* $self->{methods} does not yet exist (or got deleted) */ + if ( !SvROK(map_ref) || SvTYPE(SvRV(map_ref)) != SVt_PVHV ) { + SV *new_map_ref = newRV_noinc((SV *)newHV()); + sv_2mortal(new_map_ref); + sv_setsv(map_ref, new_map_ref); + } + + if ( !SvOK(cache_flag) || SvUV(cache_flag) != current ) { + mop_update_method_map(aTHX_ self, class_name, stash, (HV *)SvRV(map_ref)); + sv_setuv(cache_flag, mop_check_package_cache_flag(aTHX_ stash)); /* update_cache_flag() */ + } + + XPUSHs(map_ref); + BOOT: INSTALL_SIMPLE_READER_WITH_KEY(Package, name, package); ++ INSTALL_SIMPLE_READER(Package, method_metaclass); ++ INSTALL_SIMPLE_READER(Package, wrapped_method_metaclass); ++ INSTALL_SIMPLE_READER_WITH_KEY(Package, _method_map, methods);