Re: [perl #34493] h2ph `extern inline' problems
[p5sagit/p5-mst-13.2.git] / av.c
diff --git a/av.c b/av.c
index a1d62fb..df2cf23 100644 (file)
--- a/av.c
+++ b/av.c
@@ -1,6 +1,7 @@
 /*    av.c
  *
- *    Copyright (c) 1991-2002, Larry Wall
+ *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ *    2000, 2001, 2002, 2003, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -99,13 +100,18 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
            }
        }
        else {
+#ifdef PERL_MALLOC_WRAP
+           static const char oom_array_extend[] =
+             "Out of memory during array extend"; /* Duplicated in pp_hot.c */
+#endif
+
            if (AvALLOC(av)) {
 #if !defined(STRANGE_MALLOC) && !defined(MYMALLOC)
                MEM_SIZE bytes;
                IV itmp;
 #endif
 
-#if defined(MYMALLOC) && !defined(LEAKTEST)
+#ifdef MYMALLOC
                newmax = malloced_size((void*)AvALLOC(av))/sizeof(SV*) - 1;
 
                if (key <= newmax) 
@@ -113,6 +119,7 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
 #endif 
                newmax = key + AvMAX(av) / 5;
              resize:
+               MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
 #if defined(STRANGE_MALLOC) || defined(MYMALLOC)
                Renew(AvALLOC(av),newmax+1, SV*);
 #else
@@ -134,7 +141,7 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
                    Safefree(AvALLOC(av));
                AvALLOC(av) = ary;
 #endif
-#if defined(MYMALLOC) && !defined(LEAKTEST)
+#ifdef MYMALLOC
              resized:
 #endif
                ary = AvALLOC(av) + AvMAX(av) + 1;
@@ -147,6 +154,7 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
            }
            else {
                newmax = key < 3 ? 3 : key;
+               MEM_WRAP_CHECK_1(newmax+1, SV*, oom_array_extend);
                New(2,AvALLOC(av), newmax+1, SV*);
                ary = AvALLOC(av) + 1;
                tmp = newmax;
@@ -185,7 +193,7 @@ Perl_av_fetch(pTHX_ register AV *av, I32 key, I32 lval)
        return 0;
 
     if (SvRMAGICAL(av)) {
-        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
+        const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
         if (tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata)) {
             U32 adjust_index = 1;
 
@@ -208,9 +216,11 @@ Perl_av_fetch(pTHX_ register AV *av, I32 key, I32 lval)
             }
 
             sv = sv_newmortal();
-            mg_copy((SV*)av, sv, 0, key);
-            PL_av_fetch_sv = sv;
-            return &PL_av_fetch_sv;
+           sv_upgrade(sv, SVt_PVLV);
+           mg_copy((SV*)av, sv, 0, key);
+           LvTYPE(sv) = 't';
+           LvTARG(sv) = sv; /* fake (SV**) */
+           return &(LvTARG(sv));
         }
     }
 
@@ -271,7 +281,7 @@ Perl_av_store(pTHX_ register AV *av, I32 key, SV *val)
        val = &PL_sv_undef;
 
     if (SvRMAGICAL(av)) {
-        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
+        const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
         if (tied_magic) {
             /* Handle negative array indices 20020222 MJD */
             if (key < 0) {
@@ -453,8 +463,11 @@ Perl_av_clear(pTHX_ register AV *av)
        ary = AvARRAY(av);
        key = AvFILLp(av) + 1;
        while (key) {
-           SvREFCNT_dec(ary[--key]);
+           SV * sv = ary[--key];
+           /* undef the slot before freeing the value, because a
+            * destructor might try to modify this arrray */
            ary[key] = &PL_sv_undef;
+           SvREFCNT_dec(sv);
        }
     }
     if ((key = AvARRAY(av) - AvALLOC(av))) {
@@ -710,7 +723,7 @@ empty.
 */
 
 I32
-Perl_av_len(pTHX_ register AV *av)
+Perl_av_len(pTHX_ const register AV *av)
 {
     return AvFILL(av);
 }
@@ -774,7 +787,8 @@ Perl_av_fill(pTHX_ register AV *av, I32 fill)
 =for apidoc av_delete
 
 Deletes the element indexed by C<key> from the array.  Returns the
-deleted element. C<flags> is currently ignored.
+deleted element. If C<flags> equals C<G_DISCARD>, the element is freed
+and null is returned.
 
 =cut
 */
@@ -789,10 +803,10 @@ Perl_av_delete(pTHX_ AV *av, I32 key, I32 flags)
        Perl_croak(aTHX_ PL_no_modify);
 
     if (SvRMAGICAL(av)) {
-        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
-        SV **svp;
+        const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
         if ((tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata))) {
             /* Handle negative array indices 20020222 MJD */
+            SV **svp;
             if (key < 0) {
                 unsigned adjust_index = 1;
                 if (tied_magic) {
@@ -832,6 +846,8 @@ Perl_av_delete(pTHX_ AV *av, I32 key, I32 flags)
     if (key > AvFILLp(av))
        return Nullsv;
     else {
+       if (!AvREAL(av) && AvREIFY(av))
+           av_reify(av);
        sv = AvARRAY(av)[key];
        if (key == AvFILLp(av)) {
            AvARRAY(av)[key] = &PL_sv_undef;
@@ -848,6 +864,8 @@ Perl_av_delete(pTHX_ AV *av, I32 key, I32 flags)
        SvREFCNT_dec(sv);
        sv = Nullsv;
     }
+    else if (AvREAL(av))
+       sv = sv_2mortal(sv);
     return sv;
 }
 
@@ -869,7 +887,7 @@ Perl_av_exists(pTHX_ AV *av, I32 key)
 
 
     if (SvRMAGICAL(av)) {
-        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
+        const MAGIC * const tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
         if (tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata)) {
             SV *sv = sv_newmortal();
             MAGIC *mg;