Class-Std-Fast_XS

 view release on metacpan or  search on metacpan

lib/Class/Std/Fast_XS.xs  view on Meta::CPAN

        parent_len = av_len(parent_from);

        // for all classes in hierarchy
        for (; i <= parent_len; ) {
            // printf("%d\n", i);
            if (base_class = av_fetch(parent_from, i++,0)) {
                // call DEMOLISH if exists
                base_class_len = SvCUR(*base_class);
                demolish(*base_class, base_class_len, object);

                //if (attr_ref = hv_fetch(global_attribute_of, SvPV_nolen(*base_class), SvCUR(*base_class), 0)) {
                if (attr_ref = hv_fetch(global_attribute_of, SvPV_nolen(*base_class), base_class_len, 0)) {
                    if (! SvROK(*attr_ref))
                        croak("Oops - not a reference");
                    attr_from = (AV*)SvRV(*attr_ref);
                    attr_len = av_len(attr_from);
                    // for all attributes in class
                    for (j = 0; j <= attr_len;) {
                        // printf("attr\n");
                        if (attr = av_fetch(attr_from, j++, 0)) {
                            if (he = hv_fetch_ent((HV*)SvRV(*attr), global_ref_key.key, 0, global_ref_key.hash)) {
                                // TODO: check whether he contains a hash ref
                                if (! SvROK(HeVAL(he)))
                                    croak("Oops - not a reference");
                                hv_delete_ent((HV*)SvRV(HeVAL(he)), ident, G_DISCARD, 0);
                            }
                        }
                    }
                }
            }
        }
        if (hv_exists(global_do_cache_class_of, class_name, len)) {
            cache_store(object, class_name, len, class_stash);
        }
    }
}

MODULE = Class::Std::Fast_XS      PACKAGE = Class::Std::Fast_XS

void destroy(object);
    SV * object;

void init(data_hash_ref, attribute_hash_ref, do_cache_class_ref, cache_ref)
    SV*     data_hash_ref;
    SV*     attribute_hash_ref;
    SV*     do_cache_class_ref;
    SV*     cache_ref;

void
getter(self)
        SV* self;
    ALIAS:
    INIT:
        /* Get the const hash key struct from the global storage */
        /* ix is the magic integer variable that is set by the perl guts for us.
         * We uses it to identify the currently running alias of the accessor. Gollum! */
        const autoxs_hashkey readfrom = AutoXS_hashkeys[ix];
        HE* he;
        HE* value_ent;
        SV* key;
    PPCODE:
        if (he = hv_fetch_ent(global_hash_ref, readfrom.key, 0, readfrom.hash)) {
            if (value_ent = hv_fetch_ent((HV*)SvRV(HeVAL(he)), SvRV(self), 0, 0)) {
                XPUSHs(HeVAL(value_ent));
            }
            else {
                XSRETURN_UNDEF;
            }
        }
        else {
            XSRETURN_UNDEF;
        }



void
setter(self, newvalue)
    SV* self;
    SV* newvalue;
  ALIAS:
  INIT:
    /* Get the const hash key struct from the global storage */
    /* ix is the magic integer variable that is set by the perl guts for us.
     * We uses it to identify the currently running alias of the accessor. Gollum! */
    const autoxs_hashkey readfrom = AutoXS_hashkeys[ix];
    HE* he;
    SV* key;

    PPCODE:
    SvREFCNT_inc(newvalue);
    if (he = hv_fetch_ent(global_hash_ref, readfrom.key, 0, readfrom.hash)) {
        key = SvRV(self);
        if (NULL == hv_store_ent((HV*)SvRV(HeVAL(he)), key, newvalue, 0)) {
          croak("Failed to write new value to hash.");
        }
    }
    XPUSHs(self);


void
newxs_getter(name, key)
  char* name;
  char* key;
  PPCODE:
    char* file = __FILE__;
    const unsigned int functionIndex = get_next_hashkey();
    {
      CV * cv;
      unsigned int len;
      autoxs_hashkey hashkey;
      /* This code is very similar to what you get from using the ALIAS XS syntax.
       * Except I took it from the generated C code. Hic sunt dragones, I suppose... */
      cv = newXS(name, XS_Class__Std__Fast_XS_getter, file);
      if (cv == NULL)
        croak("ARG! SOMETHING WENT REALLY WRONG!");
      XSANY.any_i32 = functionIndex;

      /* Precompute the hash of the key and store it in the global structure */
      len = strlen(key);
      hashkey.key = newSVpvn(key, len);
      PERL_HASH(hashkey.hash, key, len);
      AutoXS_hashkeys[functionIndex] = hashkey;
    }


void
newxs_setter(name, key)
  char* name;
  char* key;
  PPCODE:
    char* file = __FILE__;
    const unsigned int functionIndex = get_next_hashkey();
    {
      CV * cv;
      unsigned int len;
      autoxs_hashkey hashkey;
      /* This code is very similar to what you get from using the ALIAS XS syntax.
       * Except I took it from the generated C code. Hic sunt dragones, I suppose... */
      cv = newXS(name, XS_Class__Std__Fast_XS_setter, file);
      if (cv == NULL)
        croak("ARG! SOMETHING WENT REALLY WRONG!");
      XSANY.any_i32 = functionIndex;

      /* Precompute the hash of the key and store it in the global structure */
      len = strlen(key);
      hashkey.key = newSVpvn(key, len);
      PERL_HASH(hashkey.hash, key, len);
      AutoXS_hashkeys[functionIndex] = hashkey;
    }



( run in 0.954 second using v1.01-cache-2.11-cpan-71847e10f99 )