On OS X to use perl's malloc need to USE_PERL_SBRK and emulate sbrk()
[p5sagit/p5-mst-13.2.git] / hv.c
diff --git a/hv.c b/hv.c
index 3d2e589..b3c6b2f 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -33,6 +33,9 @@ holds the key and hash value.
 
 #define HV_MAX_LENGTH_BEFORE_SPLIT 14
 
+static const char *const S_strtab_error
+    = "Cannot modify shared string table in hv_%s";
+
 STATIC void
 S_more_he(pTHX)
 {
@@ -131,7 +134,7 @@ Perl_hek_dup(pTHX_ HEK *source, CLONE_PARAMS* param)
 
     if (shared) {
        /* We already shared this hash key.  */
-       share_hek_hek(shared);
+       (void)share_hek_hek(shared);
     }
     else {
        shared
@@ -168,12 +171,12 @@ Perl_he_dup(pTHX_ HE *e, bool shared, CLONE_PARAMS* param)
     else if (shared) {
        /* This is hek_dup inlined, which seems to be important for speed
           reasons.  */
-       HEK *source = HeKEY_hek(e);
+       HEK * const source = HeKEY_hek(e);
        HEK *shared = (HEK*)ptr_table_fetch(PL_ptr_table, source);
 
        if (shared) {
            /* We already shared this hash key.  */
-           share_hek_hek(shared);
+           (void)share_hek_hek(shared);
        }
        else {
            shared
@@ -195,7 +198,7 @@ static void
 S_hv_notallowed(pTHX_ int flags, const char *key, I32 klen,
                const char *msg)
 {
-    SV *sv = sv_newmortal();
+    SV * const sv = sv_newmortal();
     if (!(flags & HVhek_FREEKEY)) {
        sv_setpvn(sv, key, klen);
     }
@@ -692,6 +695,14 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
                    unshare_hek (HeKEY_hek(entry));
                    HeKEY_hek(entry) = new_hek;
                }
+               else if (hv == PL_strtab) {
+                   /* PL_strtab is usually the only hash without HvSHAREKEYS,
+                      so putting this test here is cheap  */
+                   if (flags & HVhek_FREEKEY)
+                       Safefree(key);
+                   Perl_croak(aTHX_ S_strtab_error,
+                              action & HV_FETCH_LVALUE ? "fetch" : "store");
+               }
                else
                    HeKFLAGS(entry) = masked_flags;
                if (masked_flags & HVhek_ENABLEHVKFLAGS)
@@ -793,6 +804,14 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
        bad API design.  */
     if (HvSHAREKEYS(hv))
        HeKEY_hek(entry) = share_hek_flags(key, klen, hash, flags);
+    else if (hv == PL_strtab) {
+       /* PL_strtab is usually the only hash without HvSHAREKEYS, so putting
+          this test here is cheap  */
+       if (flags & HVhek_FREEKEY)
+           Safefree(key);
+       Perl_croak(aTHX_ S_strtab_error,
+                  action & HV_FETCH_LVALUE ? "fetch" : "store");
+    }
     else                                       /* gotta do the real thing */
        HeKEY_hek(entry) = save_hek_flags(key, klen, hash, flags);
     HeVAL(entry) = val;
@@ -1036,6 +1055,12 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
        if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8)
            continue;
 
+       if (hv == PL_strtab) {
+           if (k_flags & HVhek_FREEKEY)
+               Safefree(key);
+           Perl_croak(aTHX_ S_strtab_error, "delete");
+       }
+
        /* if placeholder is here, it's already been deleted.... */
        if (HeVAL(entry) == &PL_sv_placeholder)
        {
@@ -2284,7 +2309,6 @@ Perl_share_hek(pTHX_ const char *str, I32 len, register U32 hash)
 STATIC HEK *
 S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
 {
-    register XPVHV* xhv;
     register HE *entry;
     register HE **oentry;
     I32 found = 0;
@@ -2298,7 +2322,7 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
        Can't rehash the shared string table, so not sure if it's worth
        counting the number of entries in the linked list
     */
-    xhv = (XPVHV*)SvANY(PL_strtab);
+    register XPVHV * const xhv = (XPVHV*)SvANY(PL_strtab);
     /* assert(xhv_array != 0) */
     LOCK_STRTAB_MUTEX;
     oentry = &(HvARRAY(PL_strtab))[hash & (I32) HvMAX(PL_strtab)];