Merge master into topic/xs-attr-template abandoned/xs-attr-template
gfx [Mon, 3 Aug 2009 08:26:40 +0000 (17:26 +0900)]
12 files changed:
1  2 
lib/Class/MOP/Attribute.pm
lib/Class/MOP/Class.pm
lib/Class/MOP/Instance.pm
lib/Class/MOP/Method.pm
lib/Class/MOP/Method/Accessor.pm
lib/Class/MOP/Method/Constructor.pm
lib/Class/MOP/Method/Generated.pm
lib/Class/MOP/Method/Inlined.pm
lib/Class/MOP/Package.pm
mop.c
xs/Class.xs
xs/Package.xs

Simple merge
@@@ -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
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -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 mop.c
Simple merge
diff --cc xs/Class.xs
index d779683,0000000..e84eae4
mode 100644,000000..100644
--- /dev/null
@@@ -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
@@@ -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);