*/
#include "EXTERN.h"
+#define PERL_IN_HV_C
#include "perl.h"
-static void hv_magic_check _((HV *hv, bool *needs_copy, bool *needs_store));
-#ifndef PERL_OBJECT
-static void hsplit _((HV *hv));
-static void hfreeentries _((HV *hv));
-static void more_he _((void));
-static HEK *save_hek _((const char *str, I32 len, U32 hash));
-#endif
-
#if defined(STRANGE_MALLOC) || defined(MYMALLOC)
# define ARRAY_ALLOC_BYTES(size) ( (size)*sizeof(HE*) )
#else
# define MALLOC_OVERHEAD 16
-# define ARRAY_ALLOC_BYTES(size) ( (size)*sizeof(HE*)*2 - MALLOC_OVERHEAD )
+# define ARRAY_ALLOC_BYTES(size) ( ((size) < 64) \
+ ? (size)*sizeof(HE*) \
+ : (size)*sizeof(HE*)*2 - MALLOC_OVERHEAD )
#endif
STATIC HE*
-new_he(void)
+S_new_he(pTHX)
{
HE* he;
LOCK_SV_MUTEX;
}
STATIC void
-del_he(HE *p)
+S_del_he(pTHX_ HE *p)
{
LOCK_SV_MUTEX;
HeNEXT(p) = (HE*)PL_he_root;
}
STATIC void
-more_he(void)
+S_more_he(pTHX)
{
register HE* he;
register HE* heend;
}
STATIC HEK *
-save_hek(const char *str, I32 len, U32 hash)
+S_save_hek(pTHX_ const char *str, I32 len, U32 hash)
{
char *k;
register HEK *hek;
}
void
-unshare_hek(HEK *hek)
+Perl_unshare_hek(pTHX_ HEK *hek)
{
unsharepvn(HEK_KEY(hek),HEK_LEN(hek),HEK_HASH(hek));
}
* contains an SV* */
SV**
-hv_fetch(HV *hv, const char *key, U32 klen, I32 lval)
+Perl_hv_fetch(pTHX_ HV *hv, const char *key, U32 klen, I32 lval)
{
register XPVHV* xhv;
register U32 hash;
}
#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */
if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) {
- char *gotenv;
-
- if ((gotenv = PerlEnv_getenv(key)) != Nullch) {
- sv = newSVpvn(gotenv,strlen(gotenv));
- SvTAINTED_on(sv);
- return hv_store(hv,key,klen,sv,hash);
- }
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ return hv_store(hv,key,klen,sv,hash);
+ }
}
#endif
if (lval) { /* gonna assign to this, so it better be there */
/* returns a HE * structure with the all fields set */
/* note that hent_val will be a mortal sv for MAGICAL hashes */
HE *
-hv_fetch_ent(HV *hv, SV *keysv, I32 lval, register U32 hash)
+Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash)
{
register XPVHV* xhv;
register char *key;
}
#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */
if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) {
- char *gotenv;
-
- if ((gotenv = PerlEnv_getenv(key)) != Nullch) {
- sv = newSVpvn(gotenv,strlen(gotenv));
- SvTAINTED_on(sv);
- return hv_store_ent(hv,keysv,sv,hash);
- }
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ return hv_store_ent(hv,keysv,sv,hash);
+ }
}
#endif
if (lval) { /* gonna assign to this, so it better be there */
return 0;
}
-static void
-hv_magic_check (HV *hv, bool *needs_copy, bool *needs_store)
+STATIC void
+S_hv_magic_check(pTHX_ HV *hv, bool *needs_copy, bool *needs_store)
{
MAGIC *mg = SvMAGIC(hv);
*needs_copy = FALSE;
}
SV**
-hv_store(HV *hv, const char *key, U32 klen, SV *val, register U32 hash)
+Perl_hv_store(pTHX_ HV *hv, const char *key, U32 klen, SV *val, register U32 hash)
{
register XPVHV* xhv;
register I32 i;
}
HE *
-hv_store_ent(HV *hv, SV *keysv, SV *val, register U32 hash)
+Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash)
{
register XPVHV* xhv;
register char *key;
}
SV *
-hv_delete(HV *hv, const char *key, U32 klen, I32 flags)
+Perl_hv_delete(pTHX_ HV *hv, const char *key, U32 klen, I32 flags)
{
register XPVHV* xhv;
register I32 i;
}
SV *
-hv_delete_ent(HV *hv, SV *keysv, I32 flags, U32 hash)
+Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash)
{
register XPVHV* xhv;
register I32 i;
}
bool
-hv_exists(HV *hv, const char *key, U32 klen)
+Perl_hv_exists(pTHX_ HV *hv, const char *key, U32 klen)
{
register XPVHV* xhv;
register U32 hash;
}
xhv = (XPVHV*)SvANY(hv);
+#ifndef DYNAMIC_ENV_FETCH
if (!xhv->xhv_array)
return 0;
+#endif
PERL_HASH(hash, key, klen);
+#ifdef DYNAMIC_ENV_FETCH
+ if (!xhv->xhv_array) entry = Null(HE*);
+ else
+#endif
entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
for (; entry; entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
return TRUE;
}
+#ifdef DYNAMIC_ENV_FETCH /* is it out there? */
+ if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME)) {
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ (void)hv_store(hv,key,klen,sv,hash);
+ return TRUE;
+ }
+ }
+#endif
return FALSE;
}
bool
-hv_exists_ent(HV *hv, SV *keysv, U32 hash)
+Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)
{
register XPVHV* xhv;
register char *key;
}
xhv = (XPVHV*)SvANY(hv);
+#ifndef DYNAMIC_ENV_FETCH
if (!xhv->xhv_array)
return 0;
+#endif
key = SvPV(keysv, klen);
if (!hash)
PERL_HASH(hash, key, klen);
+#ifdef DYNAMIC_ENV_FETCH
+ if (!xhv->xhv_array) entry = Null(HE*);
+ else
+#endif
entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max];
for (; entry; entry = HeNEXT(entry)) {
if (HeHASH(entry) != hash) /* strings can't be equal */
continue;
return TRUE;
}
+#ifdef DYNAMIC_ENV_FETCH /* is it out there? */
+ if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME)) {
+ unsigned long len;
+ char *env = PerlEnv_ENVgetenv_len(key,&len);
+ if (env) {
+ sv = newSVpvn(env,len);
+ SvTAINTED_on(sv);
+ (void)hv_store_ent(hv,keysv,sv,hash);
+ return TRUE;
+ }
+ }
+#endif
return FALSE;
}
STATIC void
-hsplit(HV *hv)
+S_hsplit(pTHX_ HV *hv)
{
register XPVHV* xhv = (XPVHV*)SvANY(hv);
I32 oldsize = (I32) xhv->xhv_max + 1; /* sic(k) */
}
void
-hv_ksplit(HV *hv, IV newmax)
+Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)
{
register XPVHV* xhv = (XPVHV*)SvANY(hv);
I32 oldsize = (I32) xhv->xhv_max + 1; /* sic(k) */
}
HV *
-newHV(void)
+Perl_newHV(pTHX)
{
register HV *hv;
register XPVHV* xhv;
}
HV *
-newHVhv(HV *ohv)
+Perl_newHVhv(pTHX_ HV *ohv)
{
register HV *hv;
STRLEN hv_max = ohv ? HvMAX(ohv) : 0;
}
void
-hv_free_ent(HV *hv, register HE *entry)
+Perl_hv_free_ent(pTHX_ HV *hv, register HE *entry)
{
SV *val;
}
void
-hv_delayfree_ent(HV *hv, register HE *entry)
+Perl_hv_delayfree_ent(pTHX_ HV *hv, register HE *entry)
{
if (!entry)
return;
}
void
-hv_clear(HV *hv)
+Perl_hv_clear(pTHX_ HV *hv)
{
register XPVHV* xhv;
if (!hv)
}
STATIC void
-hfreeentries(HV *hv)
+S_hfreeentries(pTHX_ HV *hv)
{
register HE **array;
register HE *entry;
}
void
-hv_undef(HV *hv)
+Perl_hv_undef(pTHX_ HV *hv)
{
register XPVHV* xhv;
if (!hv)
}
I32
-hv_iterinit(HV *hv)
+Perl_hv_iterinit(pTHX_ HV *hv)
{
register XPVHV* xhv;
HE *entry;
if (!hv)
- croak("Bad hash");
+ Perl_croak(aTHX_ "Bad hash");
xhv = (XPVHV*)SvANY(hv);
entry = xhv->xhv_eiter;
-#ifdef DYNAMIC_ENV_FETCH /* set up %ENV for iteration */
- if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME))
- prime_env_iter();
-#endif
if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */
HvLAZYDEL_off(hv);
hv_free_ent(hv, entry);
}
HE *
-hv_iternext(HV *hv)
+Perl_hv_iternext(pTHX_ HV *hv)
{
register XPVHV* xhv;
register HE *entry;
MAGIC* mg;
if (!hv)
- croak("Bad hash");
+ Perl_croak(aTHX_ "Bad hash");
xhv = (XPVHV*)SvANY(hv);
oldentry = entry = xhv->xhv_eiter;
xhv->xhv_eiter = Null(HE*);
return Null(HE*);
}
+#ifdef DYNAMIC_ENV_FETCH /* set up %ENV for iteration */
+ if (!entry && HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME))
+ prime_env_iter();
+#endif
if (!xhv->xhv_array)
Newz(506,xhv->xhv_array, ARRAY_ALLOC_BYTES(xhv->xhv_max + 1), char);
}
char *
-hv_iterkey(register HE *entry, I32 *retlen)
+Perl_hv_iterkey(pTHX_ register HE *entry, I32 *retlen)
{
if (HeKLEN(entry) == HEf_SVKEY) {
STRLEN len;
/* unlike hv_iterval(), this always returns a mortal copy of the key */
SV *
-hv_iterkeysv(register HE *entry)
+Perl_hv_iterkeysv(pTHX_ register HE *entry)
{
if (HeKLEN(entry) == HEf_SVKEY)
return sv_mortalcopy(HeKEY_sv(entry));
}
SV *
-hv_iterval(HV *hv, register HE *entry)
+Perl_hv_iterval(pTHX_ HV *hv, register HE *entry)
{
if (SvRMAGICAL(hv)) {
if (mg_find((SV*)hv,'P')) {
}
SV *
-hv_iternextsv(HV *hv, char **key, I32 *retlen)
+Perl_hv_iternextsv(pTHX_ HV *hv, char **key, I32 *retlen)
{
HE *he;
if ( (he = hv_iternext(hv)) == NULL)
}
void
-hv_magic(HV *hv, GV *gv, int how)
+Perl_hv_magic(pTHX_ HV *hv, GV *gv, int how)
{
sv_magic((SV*)hv, (SV*)gv, how, Nullch, 0);
}
char*
-sharepvn(const char *sv, I32 len, U32 hash)
+Perl_sharepvn(pTHX_ const char *sv, I32 len, U32 hash)
{
return HEK_KEY(share_hek(sv, len, hash));
}
* len and hash must both be valid for str.
*/
void
-unsharepvn(const char *str, I32 len, U32 hash)
+Perl_unsharepvn(pTHX_ const char *str, I32 len, U32 hash)
{
register XPVHV* xhv;
register HE *entry;
}
UNLOCK_STRTAB_MUTEX;
- if (!found)
- warn("Attempt to free non-existent shared string");
+ {
+ dTHR;
+ if (!found && ckWARN_d(WARN_INTERNAL))
+ Perl_warner(aTHX_ WARN_INTERNAL, "Attempt to free non-existent shared string");
+ }
}
/* get a (constant) string ptr from the global string table
* len and hash must both be valid for str.
*/
HEK *
-share_hek(const char *str, I32 len, register U32 hash)
+Perl_share_hek(pTHX_ const char *str, I32 len, register U32 hash)
{
register XPVHV* xhv;
register HE *entry;