This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
devel/scanprov: Extract code into a fcn
[perl5.git] / av.c
diff --git a/av.c b/av.c
index ba97fed..f10f124 100644 (file)
--- a/av.c
+++ b/av.c
@@ -140,17 +140,13 @@ Perl_av_extend_guts(pTHX_ AV *av, SSize_t key, SSize_t *maxp, SV ***allocp,
                             ? SSize_t_MAX : key + newmax;
              resize:
                {
-#ifdef PERL_MALLOC_WRAP /* Duplicated in pp_hot.c */
-                   static const char oom_array_extend[] =
-                       "Out of memory during array extend";
-#endif
                     /* it should really be newmax+1 here, but if newmax
                      * happens to equal SSize_t_MAX, then newmax+1 is
                      * undefined. This means technically we croak one
                      * index lower than we should in theory; in practice
                      * its unlikely the system has SSize_t_MAX/sizeof(SV*)
                      * bytes to spare! */
-                   MEM_WRAP_CHECK_1(newmax, SV*, oom_array_extend);
+                   MEM_WRAP_CHECK_s(newmax, SV*, "Out of memory during array extend");
                }
 #ifdef STRESS_REALLOC
                {
@@ -176,12 +172,8 @@ Perl_av_extend_guts(pTHX_ AV *av, SSize_t key, SSize_t *maxp, SV ***allocp,
            else {
                newmax = key < 3 ? 3 : key;
                {
-#ifdef PERL_MALLOC_WRAP /* Duplicated in pp_hot.c */
-                   static const char oom_array_extend[] =
-                       "Out of memory during array extend";
-#endif
                     /* see comment above about newmax+1*/
-                   MEM_WRAP_CHECK_1(newmax, SV*, oom_array_extend);
+                   MEM_WRAP_CHECK_s(newmax, SV*, "Out of memory during array extend");
                }
                Newx(*allocp, newmax+1, SV*);
                ary = *allocp + 1;
@@ -364,8 +356,8 @@ Perl_av_store(pTHX_ AV *av, SSize_t key, SV *val)
        }
        AvFILLp(av) = key;
     }
-    else if (AvREAL(av))
-       SvREFCNT_dec(ary[key]);
+    else if (AvREAL(av) && LIKELY(ary[key] != val))
+        SvREFCNT_dec(ary[key]);
     ary[key] = val;
     if (SvSMAGICAL(av)) {
        const MAGIC *mg = SvMAGIC(av);
@@ -1015,6 +1007,9 @@ Perl_av_exists(pTHX_ AV *av, SSize_t key)
 
     if (key <= AvFILLp(av) && AvARRAY(av)[key])
     {
+       if (SvSMAGICAL(AvARRAY(av)[key])
+        && mg_find(AvARRAY(av)[key], PERL_MAGIC_nonelem))
+           return FALSE;
        return TRUE;
     }
     else
@@ -1070,6 +1065,16 @@ Perl_av_iter_p(pTHX_ AV *av) {
     }
 }
 
+SV *
+Perl_av_nonelem(pTHX_ AV *av, SSize_t ix) {
+    SV * const sv = newSV(0);
+    PERL_ARGS_ASSERT_AV_NONELEM;
+    if (!av_store(av,ix,sv))
+       return sv_2mortal(sv); /* has tie magic */
+    sv_magic(sv, NULL, PERL_MAGIC_nonelem, NULL, 0);
+    return sv;
+}
+
 /*
  * ex: set ts=8 sts=4 sw=4 et:
  */