X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/c418a2d4058f874e3e9e0ab21b18e09562439579..0dbc1c87c2e8a14e9699b610e0307f70ab81318b:/ext/Hash/Util/FieldHash/FieldHash.xs diff --git a/ext/Hash/Util/FieldHash/FieldHash.xs b/ext/Hash/Util/FieldHash/FieldHash.xs index 8dadc74..44ff3ce 100644 --- a/ext/Hash/Util/FieldHash/FieldHash.xs +++ b/ext/Hash/Util/FieldHash/FieldHash.xs @@ -4,13 +4,12 @@ /* support for Hash::Util::FieldHash, prefix HUF_ */ -/* The object registry, a package variable */ -#define HUF_OB_REG "Hash::Util::FieldHash::ob_reg" +/* A Perl sub that returns a hashref to the object registry */ +#define HUF_OB_REG "Hash::Util::FieldHash::_ob_reg" /* Magic cookies to recognize object id's. Hi, Eva, David */ #define HUF_COOKIE 2805.1980 #define HUF_REFADDR_COOKIE 1811.1976 - /* For global cache of object registry */ #define MY_CXT_KEY "Hash::Util::FieldHash::_guts" XS_VERSION typedef struct { @@ -18,6 +17,30 @@ typedef struct { } my_cxt_t; START_MY_CXT +/* Inquire the object registry (a lexical hash) from perl */ +HV* HUF_get_ob_reg(void) { + dSP; + HV* ob_reg = NULL; + I32 items; + ENTER; + SAVETMPS; + + PUSHMARK(SP); + items = call_pv(HUF_OB_REG, G_SCALAR|G_NOARGS); + SPAGAIN; + + if (items == 1 && TOPs && SvROK(TOPs) && SvTYPE(SvRV(TOPs)) == SVt_PVHV) { + ob_reg = (HV*)SvRV(POPs); + } + PUTBACK; + FREETMPS; + LEAVE; + + if (ob_reg) + return ob_reg; + Perl_die(aTHX_ "Can't get object registry hash"); +} + /* Deal with global context */ #define HUF_INIT 1 #define HUF_CLONE 0 @@ -26,13 +49,13 @@ START_MY_CXT void HUF_global(I32 how) { if (how == HUF_INIT) { MY_CXT_INIT; - MY_CXT.ob_reg = get_hv(HUF_OB_REG, 1); + MY_CXT.ob_reg = HUF_get_ob_reg(); } else if (how == HUF_CLONE) { MY_CXT_CLONE; - MY_CXT.ob_reg = get_hv(HUF_OB_REG, 0); + MY_CXT.ob_reg = HUF_get_ob_reg(); } else if (how == HUF_RESET) { dMY_CXT; - MY_CXT.ob_reg = get_hv(HUF_OB_REG, 0); + MY_CXT.ob_reg = HUF_get_ob_reg(); } } @@ -46,7 +69,7 @@ SV* HUF_id(SV* ref, NV cookie) { SvNV_set(id, cookie); SvNOK_on(id); } - SvIV_set(id, (IV)SvRV(ref)); + SvIV_set(id, PTR2UV(SvRV(ref))); SvIOK_on(id); return id; } @@ -56,14 +79,14 @@ SV* HUF_field_id(SV* obj) { return HUF_id(obj, 0.0); } -/* object id (may be different in future) */ +/* object id (same as plain, may be different in future) */ SV* HUF_obj_id(SV* obj) { return HUF_id(obj, 0.0); } /* set up uvar magic for any sv */ void HUF_add_uvar_magic( - SV* sv, /* the sv to enchant, visible to * get/set */ + SV* sv, /* the sv to enchant, visible to get/set */ I32(* val)(pTHX_ IV, SV*), /* "get" function */ I32(* set)(pTHX_ IV, SV*), /* "set" function */ I32 index, /* get/set will see this */ @@ -155,6 +178,8 @@ void HUF_mark_field(SV* trigger, SV* field) { hv_store_ent(field_tab, field_id, field_ref, 0); } +/* These constants are not in the API. If they ever change in hv.c this code + * must be updated */ #define HV_FETCH_ISSTORE 0x01 #define HV_FETCH_ISEXISTS 0x02 #define HV_FETCH_LVALUE 0x04 @@ -166,7 +191,10 @@ void HUF_mark_field(SV* trigger, SV* field) { * in hv.c */ I32 HUF_watch_key(pTHX_ IV action, SV* field) { MAGIC* mg = mg_find(field, PERL_MAGIC_uvar); - SV* keysv = mg->mg_obj; + SV* keysv; + if (!mg) + Perl_die(aTHX_ "Rogue call of 'HUF_watch_key'"); + keysv = mg->mg_obj; if (keysv && SvROK(keysv)) { SV* ob_id = HUF_obj_id(keysv); mg->mg_obj = ob_id; /* key replacement */ @@ -221,7 +249,7 @@ void HUF_fix_trigger(SV* trigger, SV* new_id) { /* Go over object registry and fix all objects. Also fix the object * registry. */ -void HUF_fix_objects() { +void HUF_fix_objects(void) { dMY_CXT; I32 i, len; HE* ent; @@ -285,15 +313,6 @@ CODE: HUF_fix_objects(); } -SV* -_get_obj_id(SV* obj) -CODE: - RETVAL = NULL; - if (SvROK(obj)) - RETVAL = HUF_obj_id(obj); -OUTPUT: - RETVAL - void _active_fields(SV* obj) PPCODE: