Globs that are in symbol table can be un-globbed
[p5sagit/p5-mst-13.2.git] / av.c
diff --git a/av.c b/av.c
index c597ea2..a3dc4dd 100644 (file)
--- a/av.c
+++ b/av.c
@@ -35,8 +35,8 @@ Perl_av_reify(pTHX_ AV *av)
     if (AvREAL(av))
        return;
 #ifdef DEBUGGING
-    if (SvTIED_mg((const SV *)av, PERL_MAGIC_tied) && ckWARN_d(WARN_DEBUGGING))
-       Perl_warner(aTHX_ packWARN(WARN_DEBUGGING), "av_reify called on tied array");
+    if (SvTIED_mg((const SV *)av, PERL_MAGIC_tied))
+       Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING), "av_reify called on tied array");
 #endif
     key = AvMAX(av) + 1;
     while (key > AvFILLp(av) + 1)
@@ -74,19 +74,9 @@ Perl_av_extend(pTHX_ AV *av, I32 key)
 
     mg = SvTIED_mg((const SV *)av, PERL_MAGIC_tied);
     if (mg) {
-       dSP;
-       ENTER;
-       SAVETMPS;
-       PUSHSTACKi(PERLSI_MAGIC);
-       PUSHMARK(SP);
-       EXTEND(SP,2);
-       PUSHs(SvTIED_obj(MUTABLE_SV(av), mg));
-       mPUSHi(key + 1);
-        PUTBACK;
-       call_method("EXTEND", G_SCALAR|G_DISCARD);
-       POPSTACK;
-       FREETMPS;
-       LEAVE;
+       SV *arg1 = sv_newmortal();
+       sv_setiv(arg1, (IV)(key + 1));
+       magic_methcall(MUTABLE_SV(av), mg, "EXTEND", G_DISCARD, 1, arg1, NULL);
        return;
     }
     if (key > AvMAX(av)) {
@@ -245,6 +235,8 @@ Perl_av_fetch(pTHX_ register AV *av, I32 key, I32 lval)
             sv = sv_newmortal();
            sv_upgrade(sv, SVt_PVLV);
            mg_copy(MUTABLE_SV(av), sv, 0, key);
+           if (!tied_magic) /* for regdata, force leavesub to make copies */
+               SvTEMP_off(sv);
            LvTYPE(sv) = 't';
            LvTARG(sv) = sv; /* fake (SV**) */
            return &(LvTARG(sv));
@@ -404,8 +396,14 @@ Perl_av_make(pTHX_ register I32 size, register SV **strp)
        AvFILLp(av) = AvMAX(av) = size - 1;
        for (i = 0; i < size; i++) {
            assert (*strp);
+
+           /* Don't let sv_setsv swipe, since our source array might
+              have multiple references to the same temp scalar (e.g.
+              from a list slice) */
+
            ary[i] = newSV(0);
-           sv_setsv(ary[i], *strp);
+           sv_setsv_flags(ary[i], *strp,
+                          SV_GMAGIC|SV_DO_COW_SVSETSV|SV_NOSTEAL);
            strp++;
        }
     }
@@ -431,8 +429,8 @@ Perl_av_clear(pTHX_ register AV *av)
     assert(SvTYPE(av) == SVt_PVAV);
 
 #ifdef DEBUGGING
-    if (SvREFCNT(av) == 0 && ckWARN_d(WARN_DEBUGGING)) {
-       Perl_warner(aTHX_ packWARN(WARN_DEBUGGING), "Attempt to clear deleted array");
+    if (SvREFCNT(av) == 0) {
+       Perl_ck_warner_d(aTHX_ packWARN(WARN_DEBUGGING), "Attempt to clear deleted array");
     }
 #endif
 
@@ -527,7 +525,8 @@ Perl_av_create_and_push(pTHX_ AV **const avp, SV *const val)
 =for apidoc av_push
 
 Pushes an SV onto the end of the array.  The array will grow automatically
-to accommodate the addition.
+to accommodate the addition. Like C<av_store>, this takes ownership of one
+reference count.
 
 =cut
 */
@@ -545,17 +544,7 @@ Perl_av_push(pTHX_ register AV *av, SV *val)
        Perl_croak(aTHX_ "%s", PL_no_modify);
 
     if ((mg = SvTIED_mg((const SV *)av, PERL_MAGIC_tied))) {
-       dSP;
-       PUSHSTACKi(PERLSI_MAGIC);
-       PUSHMARK(SP);
-       EXTEND(SP,2);
-       PUSHs(SvTIED_obj(MUTABLE_SV(av), mg));
-       PUSHs(val);
-       PUTBACK;
-       ENTER;
-       call_method("PUSH", G_SCALAR|G_DISCARD);
-       LEAVE;
-       POPSTACK;
+       magic_methcall(MUTABLE_SV(av), mg, "PUSH", G_DISCARD, 1, val, NULL);
        return;
     }
     av_store(av,AvFILLp(av)+1,val);
@@ -583,19 +572,9 @@ Perl_av_pop(pTHX_ register AV *av)
     if (SvREADONLY(av))
        Perl_croak(aTHX_ "%s", PL_no_modify);
     if ((mg = SvTIED_mg((const SV *)av, PERL_MAGIC_tied))) {
-       dSP;    
-       PUSHSTACKi(PERLSI_MAGIC);
-       PUSHMARK(SP);
-       XPUSHs(SvTIED_obj(MUTABLE_SV(av), mg));
-       PUTBACK;
-       ENTER;
-       if (call_method("POP", G_SCALAR)) {
-           retval = newSVsv(*PL_stack_sp--);    
-       } else {    
-           retval = &PL_sv_undef;
-       }
-       LEAVE;
-       POPSTACK;
+       retval = magic_methcall(MUTABLE_SV(av), mg, "POP", 0, 0, NULL, NULL);
+       if (retval)
+           retval = newSVsv(retval);
        return retval;
     }
     if (AvFILL(av) < 0)
@@ -653,19 +632,8 @@ Perl_av_unshift(pTHX_ register AV *av, register I32 num)
        Perl_croak(aTHX_ "%s", PL_no_modify);
 
     if ((mg = SvTIED_mg((const SV *)av, PERL_MAGIC_tied))) {
-       dSP;
-       PUSHSTACKi(PERLSI_MAGIC);
-       PUSHMARK(SP);
-       EXTEND(SP,1+num);
-       PUSHs(SvTIED_obj(MUTABLE_SV(av), mg));
-       while (num-- > 0) {
-           PUSHs(&PL_sv_undef);
-       }
-       PUTBACK;
-       ENTER;
-       call_method("UNSHIFT", G_SCALAR|G_DISCARD);
-       LEAVE;
-       POPSTACK;
+       magic_methcall(MUTABLE_SV(av), mg, "UNSHIFT", G_DISCARD,
+           -num, NULL, NULL);
        return;
     }
 
@@ -725,19 +693,9 @@ Perl_av_shift(pTHX_ register AV *av)
     if (SvREADONLY(av))
        Perl_croak(aTHX_ "%s", PL_no_modify);
     if ((mg = SvTIED_mg((const SV *)av, PERL_MAGIC_tied))) {
-       dSP;
-       PUSHSTACKi(PERLSI_MAGIC);
-       PUSHMARK(SP);
-       XPUSHs(SvTIED_obj(MUTABLE_SV(av), mg));
-       PUTBACK;
-       ENTER;
-       if (call_method("SHIFT", G_SCALAR)) {
-           retval = newSVsv(*PL_stack_sp--);            
-       } else {    
-           retval = &PL_sv_undef;
-       }     
-       LEAVE;
-       POPSTACK;
+       retval = magic_methcall(MUTABLE_SV(av), mg, "SHIFT", 0, 0, NULL, NULL);
+       if (retval)
+           retval = newSVsv(retval);
        return retval;
     }
     if (AvFILL(av) < 0)
@@ -797,19 +755,10 @@ Perl_av_fill(pTHX_ register AV *av, I32 fill)
     if (fill < 0)
        fill = -1;
     if ((mg = SvTIED_mg((const SV *)av, PERL_MAGIC_tied))) {
-       dSP;            
-       ENTER;
-       SAVETMPS;
-       PUSHSTACKi(PERLSI_MAGIC);
-       PUSHMARK(SP);
-       EXTEND(SP,2);
-       PUSHs(SvTIED_obj(MUTABLE_SV(av), mg));
-       mPUSHi(fill + 1);
-       PUTBACK;
-       call_method("STORESIZE", G_SCALAR|G_DISCARD);
-       POPSTACK;
-       FREETMPS;
-       LEAVE;
+       SV *arg1 = sv_newmortal();
+       sv_setiv(arg1, (IV)(fill + 1));
+       magic_methcall(MUTABLE_SV(av), mg, "STORESIZE", G_DISCARD,
+               1, arg1, NULL);
        return;
     }
     if (fill <= AvMAX(av)) {
@@ -970,7 +919,7 @@ Perl_av_exists(pTHX_ AV *av, I32 key)
             mg = mg_find(sv, PERL_MAGIC_tiedelem);
             if (mg) {
                 magic_existspack(sv, mg);
-                return (bool)SvTRUE(sv);
+                return cBOOL(SvTRUE(sv));
             }
 
         }