summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
authorNick Ing-Simmons <nik@tiuk.ti.com>1997-11-26 00:50:10 +0000
committerNick Ing-Simmons <nik@tiuk.ti.com>1997-11-26 00:50:10 +0000
commitbe679a9b8e5b022d9dbcf8917ef39627830b4ca2 (patch)
tree182157292fc7453c5fab3d80135d08f669138dc8 /hv.c
parentd40103885dfef00fdafa10024e6e4d5e414d1403 (diff)
parentfb54173c01796b37b2259a6538d910d610b2edbb (diff)
downloadperl-be679a9b8e5b022d9dbcf8917ef39627830b4ca2.tar.gz
Integrate mainline as of _55
p4raw-id: //depot/ansiperl@305
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c67
1 files changed, 44 insertions, 23 deletions
diff --git a/hv.c b/hv.c
index f3ab6ccbb9..e495e91769 100644
--- a/hv.c
+++ b/hv.c
@@ -216,6 +216,29 @@ hv_fetch_ent(HV *hv, SV *keysv, I32 lval, register U32 hash)
return 0;
}
+static void
+hv_magic_check (hv, needs_copy, needs_store)
+HV *hv;
+bool *needs_copy;
+bool *needs_store;
+{
+ MAGIC *mg = SvMAGIC(hv);
+ *needs_copy = FALSE;
+ *needs_store = TRUE;
+ while (mg) {
+ if (isUPPER(mg->mg_type)) {
+ *needs_copy = TRUE;
+ switch (mg->mg_type) {
+ case 'P':
+ case 'I':
+ case 'S':
+ *needs_store = FALSE;
+ }
+ }
+ mg = mg->mg_moremagic;
+ }
+}
+
SV**
hv_store(HV *hv, char *key, U32 klen, SV *val, register U32 hash)
{
@@ -229,15 +252,14 @@ hv_store(HV *hv, char *key, U32 klen, SV *val, register U32 hash)
xhv = (XPVHV*)SvANY(hv);
if (SvMAGICAL(hv)) {
- mg_copy((SV*)hv, val, key, klen);
- if (!xhv->xhv_array
- && (SvMAGIC(hv)->mg_moremagic
- || (SvMAGIC(hv)->mg_type != 'E'
-#ifdef OVERLOAD
- && SvMAGIC(hv)->mg_type != 'A'
-#endif /* OVERLOAD */
- )))
- return 0;
+ bool needs_copy;
+ bool needs_store;
+ hv_magic_check (hv, &needs_copy, &needs_store);
+ if (needs_copy) {
+ mg_copy((SV*)hv, val, key, klen);
+ if (!xhv->xhv_array && !needs_store)
+ return 0;
+ }
}
if (!hash)
PERL_HASH(hash, key, klen);
@@ -295,20 +317,19 @@ hv_store_ent(HV *hv, SV *keysv, SV *val, register U32 hash)
xhv = (XPVHV*)SvANY(hv);
if (SvMAGICAL(hv)) {
dTHR;
- bool save_taint = tainted;
- if (tainting)
- tainted = SvTAINTED(keysv);
- keysv = sv_2mortal(newSVsv(keysv));
- mg_copy((SV*)hv, val, (char*)keysv, HEf_SVKEY);
- TAINT_IF(save_taint);
- if (!xhv->xhv_array
- && (SvMAGIC(hv)->mg_moremagic
- || (SvMAGIC(hv)->mg_type != 'E'
-#ifdef OVERLOAD
- && SvMAGIC(hv)->mg_type != 'A'
-#endif /* OVERLOAD */
- )))
- return Nullhe;
+ bool needs_copy;
+ bool needs_store;
+ hv_magic_check (hv, &needs_copy, &needs_store);
+ if (needs_copy) {
+ bool save_taint = tainted;
+ if (tainting)
+ tainted = SvTAINTED(keysv);
+ keysv = sv_2mortal(newSVsv(keysv));
+ mg_copy((SV*)hv, val, (char*)keysv, HEf_SVKEY);
+ TAINT_IF(save_taint);
+ if (!xhv->xhv_array && !needs_store)
+ return Nullhe;
+ }
}
key = SvPV(keysv, klen);