This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Bump version number to 5.10.0.
[perl5.git] / av.c
diff --git a/av.c b/av.c
index 22eb671..07d8e22 100644 (file)
--- a/av.c
+++ b/av.c
@@ -342,11 +342,14 @@ Perl_av_store(pTHX_ register AV *av, I32 key, SV *val)
        SvREFCNT_dec(ary[key]);
     ary[key] = val;
     if (SvSMAGICAL(av)) {
+       const MAGIC* const mg = SvMAGIC(av);
        if (val != &PL_sv_undef) {
-           const MAGIC* const mg = SvMAGIC(av);
            sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
        }
-       mg_set((SV*)av);
+       if (PL_delaymagic && mg->mg_type == PERL_MAGIC_isa)
+           PL_delaymagic |= DM_ARRAY;
+       else
+          mg_set((SV*)av);
     }
     return &ary[key];
 }
@@ -362,9 +365,7 @@ Creates a new AV.  The reference count is set to 1.
 AV *
 Perl_newAV(pTHX)
 {
-    register AV * const av = (AV*)newSV(0);
-
-    sv_upgrade((SV *)av, SVt_PVAV);
+    register AV * const av = (AV*)newSV_type(SVt_PVAV);
     /* sv_upgrade does AvREAL_only()  */
     AvALLOC(av) = 0;
     AvARRAY(av) = NULL;
@@ -385,9 +386,7 @@ will have a reference count of 1.
 AV *
 Perl_av_make(pTHX_ register I32 size, register SV **strp)
 {
-    register AV * const av = (AV*)newSV(0);
-
-    sv_upgrade((SV *) av,SVt_PVAV);
+    register AV * const av = (AV*)newSV_type(SVt_PVAV);
     /* sv_upgrade does AvREAL_only()  */
     if (size) {                /* "defined" was returning undef for size==0 anyway. */
         register SV** ary;
@@ -432,8 +431,13 @@ Perl_av_clear(pTHX_ register AV *av)
        Perl_croak(aTHX_ PL_no_modify);
 
     /* Give any tie a chance to cleanup first */
-    if (SvRMAGICAL(av))
-       mg_clear((SV*)av); 
+    if (SvRMAGICAL(av)) {
+       const MAGIC* const mg = SvMAGIC(av);
+       if (PL_delaymagic && mg->mg_type == PERL_MAGIC_isa)
+           PL_delaymagic |= DM_ARRAY;
+        else
+           mg_clear((SV*)av); 
+    }
 
     if (AvMAX(av) < 0)
        return;
@@ -473,17 +477,38 @@ Perl_av_undef(pTHX_ register AV *av)
 
     /* Give any tie a chance to cleanup first */
     if (SvTIED_mg((SV*)av, PERL_MAGIC_tied)) 
-       av_fill(av, -1);   /* mg_clear() ? */
+       av_fill(av, -1);
 
     if (AvREAL(av)) {
        register I32 key = AvFILLp(av) + 1;
        while (key)
            SvREFCNT_dec(AvARRAY(av)[--key]);
     }
+
     Safefree(AvALLOC(av));
     AvALLOC(av) = NULL;
     AvARRAY(av) = NULL;
     AvMAX(av) = AvFILLp(av) = -1;
+
+    if(SvRMAGICAL(av)) mg_clear((SV*)av);
+}
+
+/*
+
+=for apidoc av_create_and_push
+
+Push an SV onto the end of the array, creating the array if necessary.
+A small internal helper function to remove a commonly duplicated idiom.
+
+=cut
+*/
+
+void
+Perl_av_create_and_push(pTHX_ AV **const avp, SV *const val)
+{
+    if (!*avp)
+       *avp = newAV();
+    av_push(*avp, val);
 }
 
 /*
@@ -568,6 +593,26 @@ Perl_av_pop(pTHX_ register AV *av)
 }
 
 /*
+
+=for apidoc av_create_and_unshift_one
+
+Unshifts an SV onto the beginning of the array, creating the array if
+necessary.
+A small internal helper function to remove a commonly duplicated idiom.
+
+=cut
+*/
+
+SV **
+Perl_av_create_and_unshift_one(pTHX_ AV **const avp, SV *const val)
+{
+    if (!*avp)
+       *avp = newAV();
+    av_unshift(*avp, 1);
+    return av_store(*avp, 0, val);
+}
+
+/*
 =for apidoc av_unshift
 
 Unshift the given number of C<undef> values onto the beginning of the
@@ -622,10 +667,9 @@ Perl_av_unshift(pTHX_ register AV *av, register I32 num)
     }
     if (num) {
        register SV **ary;
-       I32 slide;
-       i = AvFILLp(av);
+       const I32 i = AvFILLp(av);
        /* Create extra elements */
-       slide = i > 0 ? i : 0;
+       const I32 slide = i > 0 ? i : 0;
        num += slide;
        av_extend(av, i + num);
        AvFILLp(av) += num;