perl 5.002beta1h patch: Configure
[p5sagit/p5-mst-13.2.git] / pp.c
diff --git a/pp.c b/pp.c
index 51287e1..048af2e 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -126,7 +126,7 @@ PP(pp_rv2gv)
        GP *ogp = GvGP(sv);
 
        SSCHECK(3);
-       SSPUSHPTR(sv);
+       SSPUSHPTR(SvREFCNT_inc(sv));
        SSPUSHPTR(ogp);
        SSPUSHINT(SAVEt_GP);
 
@@ -200,6 +200,8 @@ PP(pp_rv2sv)
            if (SvGMAGICAL(sv))
                mg_get(sv);
            if (!SvOK(sv)) {
+               if (SvREADONLY(sv))
+                   croak(no_modify);
                (void)SvUPGRADE(sv, SVt_RV);
                SvRV(sv) = (op->op_private & OPpDEREF_HV ?
                            (SV*)newHV() : (SV*)newAV());
@@ -256,9 +258,12 @@ PP(pp_rv2cv)
     GV *gv;
     HV *stash;
 
-    /* We always try to add a non-existent subroutine in case of AUTOLOAD. */
-    CV *cv = sv_2cv(TOPs, &stash, &gv, TRUE);
+    /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
+    /* (But not in defined().) */
+    CV *cv = sv_2cv(TOPs, &stash, &gv, !(op->op_flags & OPf_SPECIAL));
 
+    if (!cv)
+       cv = (CV*)&sv_undef;
     SETs((SV*)cv);
     RETURN;
 }
@@ -270,7 +275,7 @@ PP(pp_anoncode)
     EXTEND(SP,1);
 
     if (SvFLAGS(cv) & SVpcv_CLONE) {
-       cv = cv_clone(cv);
+       cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
     }
 
     PUSHs((SV*)cv);
@@ -329,7 +334,7 @@ PP(pp_ref)
 
     sv = POPs;
     if (!sv || !SvROK(sv))
-       RETPUSHUNDEF;
+       RETPUSHNO;
 
     sv = SvRV(sv);
     pv = sv_reftype(sv,TRUE);
@@ -481,11 +486,11 @@ PP(pp_defined)
        RETPUSHNO;
     switch (SvTYPE(sv)) {
     case SVt_PVAV:
-       if (AvMAX(sv) >= 0)
+       if (AvMAX(sv) >= 0 || SvRMAGICAL(sv))
            RETPUSHYES;
        break;
     case SVt_PVHV:
-       if (HvARRAY(sv))
+       if (HvARRAY(sv) || SvRMAGICAL(sv))
            RETPUSHYES;
        break;
     case SVt_PVCV:
@@ -533,17 +538,20 @@ PP(pp_undef)
        cv_undef((CV*)sv);
        sub_generation++;
        break;
+    case SVt_PVGV:
+        if (SvFAKE(sv)) {
+            sv_setsv(sv, &sv_undef);
+            break;
+        }
     default:
-       if (sv != GvSV(defgv)) {
-           if (SvPOK(sv) && SvLEN(sv)) {
-               (void)SvOOK_off(sv);
-               Safefree(SvPVX(sv));
-               SvPV_set(sv, Nullch);
-               SvLEN_set(sv, 0);
-           }
-           (void)SvOK_off(sv);
-           SvSETMAGIC(sv);
+       if (SvPOK(sv) && SvLEN(sv)) {
+           (void)SvOOK_off(sv);
+           Safefree(SvPVX(sv));
+           SvPV_set(sv, Nullch);
+           SvLEN_set(sv, 0);
        }
+       (void)SvOK_off(sv);
+       SvSETMAGIC(sv);
     }
 
     RETPUSHUNDEF;
@@ -885,7 +893,7 @@ PP(pp_bit_and) {
     dSP; dATARGET; tryAMAGICbin(band,opASSIGN); 
     {
       dPOPTOPssrl;
-      if (SvNIOK(left) || SvNIOK(right)) {
+      if (SvNIOKp(left) || SvNIOKp(right)) {
        unsigned long value = U_L(SvNV(left));
        value = value & U_L(SvNV(right));
        SETn((double)value);
@@ -903,7 +911,7 @@ PP(pp_bit_xor)
     dSP; dATARGET; tryAMAGICbin(bxor,opASSIGN); 
     {
       dPOPTOPssrl;
-      if (SvNIOK(left) || SvNIOK(right)) {
+      if (SvNIOKp(left) || SvNIOKp(right)) {
        unsigned long value = U_L(SvNV(left));
        value = value ^ U_L(SvNV(right));
        SETn((double)value);
@@ -921,7 +929,7 @@ PP(pp_bit_or)
     dSP; dATARGET; tryAMAGICbin(bor,opASSIGN); 
     {
       dPOPTOPssrl;
-      if (SvNIOK(left) || SvNIOK(right)) {
+      if (SvNIOKp(left) || SvNIOKp(right)) {
        unsigned long value = U_L(SvNV(left));
        value = value | U_L(SvNV(right));
        SETn((double)value);
@@ -939,9 +947,11 @@ PP(pp_negate)
     dSP; dTARGET; tryAMAGICun(neg);
     {
        dTOPss;
-       if (SvNIOK(sv))
+       if (SvGMAGICAL(sv))
+           mg_get(sv);
+       if (SvNIOKp(sv))
            SETn(-SvNV(sv));
-       else if (SvPOK(sv)) {
+       else if (SvPOKp(sv)) {
            STRLEN len;
            char *s = SvPV(sv, len);
            if (isALPHA(*s) || *s == '_') {
@@ -956,6 +966,8 @@ PP(pp_negate)
                sv_setnv(TARG, -SvNV(sv));
            SETTARG;
        }
+       else
+           SETn(-SvNV(sv));
     }
     RETURN;
 }
@@ -976,7 +988,7 @@ PP(pp_complement)
       dTOPss;
       register I32 anum;
 
-      if (SvNIOK(sv)) {
+      if (SvNIOKp(sv)) {
        IV iv = ~SvIV(sv);
        if (iv < 0)
            SETn( (double) ~U_L(SvNV(sv)) );
@@ -1880,6 +1892,8 @@ PP(pp_lslice)
     SV **firstlelem = stack_base + POPMARK + 1;
     register SV **firstrelem = lastlelem + 1;
     I32 arybase = curcop->cop_arybase;
+    I32 lval = op->op_flags & OPf_MOD;
+    I32 is_something_there = lval;
 
     register I32 max = lastrelem - lastlelem;
     register SV **lelem;
@@ -1918,8 +1932,13 @@ PP(pp_lslice)
            if (ix >= max || !(*lelem = firstrelem[ix]))
                *lelem = &sv_undef;
        }
+       if (!is_something_there && (SvOKp(*lelem) || SvGMAGICAL(*lelem)))
+           is_something_there = TRUE;
     }
-    SP = lastlelem;
+    if (is_something_there)
+       SP = lastlelem;
+    else
+       SP = firstlelem - 1;
     RETURN;
 }
 
@@ -3391,7 +3410,7 @@ PP(pp_split)
     else {
        maxiters += (strend - s) * rx->nparens;
        while (s < strend && --limit &&
-           regexec(rx, s, strend, orig, 1, Nullsv, TRUE) ) {
+           pregexec(rx, s, strend, orig, 1, Nullsv, TRUE) ) {
            if (rx->subbase
              && rx->subbase != orig) {
                m = s;