[win32] add archname to *sitearch in config.{b,g,v}c
[p5sagit/p5-mst-13.2.git] / pp.c
diff --git a/pp.c b/pp.c
index 3513dda..7864089 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -24,7 +24,7 @@
  */
 #ifdef CXUX_BROKEN_CONSTANT_CONVERT
 static double UV_MAX_cxux = ((double)UV_MAX);
-#endif
+#endif  
 
 /*
  * Types used in bitwise operations.
@@ -105,9 +105,17 @@ static bool srand_called = FALSE;
 
 /* variations on pp_null */
 
+#ifdef DONT_DECLARE_STD
+#ifdef I_UNISTD
+#include <unistd.h>
+#endif
+#else
+extern pid_t getpid (void);
+#endif
+
 PP(pp_stub)
 {
-    dSP;
+    djSP;
     if (GIMME_V == G_SCALAR)
        XPUSHs(&sv_undef);
     RETURN;
@@ -122,7 +130,7 @@ PP(pp_scalar)
 
 PP(pp_padav)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     if (op->op_private & OPpLVAL_INTRO)
        SAVECLEARSV(curpad[op->op_targ]);
     EXTEND(SP, 1);
@@ -147,7 +155,7 @@ PP(pp_padav)
 
 PP(pp_padhv)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     I32 gimme;
 
     XPUSHs(TARG);
@@ -180,7 +188,7 @@ PP(pp_padany)
 
 PP(pp_rv2gv)
 {
-    dSP; dTOPss;
+    djSP; dTOPss;
     
     if (SvROK(sv)) {
       wasref:
@@ -225,7 +233,7 @@ PP(pp_rv2gv)
 
 PP(pp_rv2sv)
 {
-    dSP; dTOPss;
+    djSP; dTOPss;
 
     if (SvROK(sv)) {
       wasref:
@@ -274,7 +282,7 @@ PP(pp_rv2sv)
 
 PP(pp_av2arylen)
 {
-    dSP;
+    djSP;
     AV *av = (AV*)TOPs;
     SV *sv = AvARYLEN(av);
     if (!sv) {
@@ -288,7 +296,7 @@ PP(pp_av2arylen)
 
 PP(pp_pos)
 {
-    dSP; dTARGET; dPOPss;
+    djSP; dTARGET; dPOPss;
     
     if (op->op_flags & OPf_MOD) {
        if (SvTYPE(TARG) < SVt_PVLV) {
@@ -317,7 +325,7 @@ PP(pp_pos)
 
 PP(pp_rv2cv)
 {
-    dSP;
+    djSP;
     GV *gv;
     HV *stash;
 
@@ -336,7 +344,7 @@ PP(pp_rv2cv)
 
 PP(pp_prototype)
 {
-    dSP;
+    djSP;
     CV *cv;
     HV *stash;
     GV *gv;
@@ -352,7 +360,7 @@ PP(pp_prototype)
 
 PP(pp_anoncode)
 {
-    dSP;
+    djSP;
     CV* cv = (CV*)curpad[op->op_targ];
     if (CvCLONE(cv))
        cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
@@ -363,14 +371,14 @@ PP(pp_anoncode)
 
 PP(pp_srefgen)
 {
-    dSP;
+    djSP;
     *SP = refto(*SP);
     RETURN;
 } 
 
 PP(pp_refgen)
 {
-    dSP; dMARK;
+    djSP; dMARK;
     if (GIMME != G_ARRAY) {
        MARK[1] = *SP;
        SP = MARK + 1;
@@ -382,8 +390,7 @@ PP(pp_refgen)
 }
 
 static SV*
-refto(sv)
-SV* sv;
+refto(SV *sv)
 {
     SV* rv;
 
@@ -408,7 +415,7 @@ SV* sv;
 
 PP(pp_ref)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     SV *sv;
     char *pv;
 
@@ -428,7 +435,7 @@ PP(pp_ref)
 
 PP(pp_bless)
 {
-    dSP;
+    djSP;
     HV *stash;
 
     if (MAXARG == 1)
@@ -446,7 +453,7 @@ PP(pp_gelem)
     SV *sv;
     SV *ref;
     char *elem;
-    dSP;
+    djSP;
 
     sv = POPs;
     elem = SvPV(sv, na);
@@ -506,7 +513,8 @@ PP(pp_gelem)
 
 PP(pp_study)
 {
-    dSP; dPOPss;
+    djSP; dPOPss;
+    register UNOP *unop = cUNOP;
     register unsigned char *s;
     register I32 pos;
     register I32 ch;
@@ -514,6 +522,14 @@ PP(pp_study)
     register I32 *snext;
     STRLEN len;
 
+    if(unop->op_first && unop->op_first->op_type == OP_PUSHRE) {
+       PMOP *pm = (PMOP *)unop->op_first;
+       SV *rv = sv_newmortal();
+       sv = newSVrv(rv, "Regexp");
+       sv_magic(sv,(SV*)ReREFCNT_inc(pm->op_pmregexp),'r',0,0);
+       RETURNX(PUSHs(rv));
+    }
+
     if (sv == lastscream) {
        if (SvSCREAM(sv))
            RETPUSHYES;
@@ -568,13 +584,13 @@ PP(pp_study)
 
 PP(pp_trans)
 {
-    dSP; dTARG;
+    djSP; dTARG;
     SV *sv;
 
     if (op->op_flags & OPf_STACKED)
        sv = POPs;
     else {
-       sv = GvSV(defgv);
+       sv = DEFSV;
        EXTEND(SP,1);
     }
     TARG = sv_newmortal();
@@ -586,7 +602,7 @@ PP(pp_trans)
 
 PP(pp_schop)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     do_chop(TARG, TOPs);
     SETTARG;
     RETURN;
@@ -594,7 +610,7 @@ PP(pp_schop)
 
 PP(pp_chop)
 {
-    dSP; dMARK; dTARGET;
+    djSP; dMARK; dTARGET;
     while (SP > MARK)
        do_chop(TARG, POPs);
     PUSHTARG;
@@ -603,14 +619,14 @@ PP(pp_chop)
 
 PP(pp_schomp)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     SETi(do_chomp(TOPs));
     RETURN;
 }
 
 PP(pp_chomp)
 {
-    dSP; dMARK; dTARGET;
+    djSP; dMARK; dTARGET;
     register I32 count = 0;
     
     while (SP > MARK)
@@ -621,7 +637,7 @@ PP(pp_chomp)
 
 PP(pp_defined)
 {
-    dSP;
+    djSP;
     register SV* sv;
 
     sv = POPs;
@@ -651,7 +667,7 @@ PP(pp_defined)
 
 PP(pp_undef)
 {
-    dSP;
+    djSP;
     SV *sv;
 
     if (!op->op_private) {
@@ -709,7 +725,7 @@ PP(pp_undef)
 
 PP(pp_predec)
 {
-    dSP;
+    djSP;
     if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
        croak(no_modify);
     if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
@@ -726,7 +742,7 @@ PP(pp_predec)
 
 PP(pp_postinc)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
        croak(no_modify);
     sv_setsv(TARG, TOPs);
@@ -747,7 +763,7 @@ PP(pp_postinc)
 
 PP(pp_postdec)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     if(SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV)
        croak(no_modify);
     sv_setsv(TARG, TOPs);
@@ -768,7 +784,7 @@ PP(pp_postdec)
 
 PP(pp_pow)
 {
-    dSP; dATARGET; tryAMAGICbin(pow,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(pow,opASSIGN); 
     {
       dPOPTOPnnrl;
       SETn( pow( left, right) );
@@ -778,7 +794,7 @@ PP(pp_pow)
 
 PP(pp_multiply)
 {
-    dSP; dATARGET; tryAMAGICbin(mult,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(mult,opASSIGN); 
     {
       dPOPTOPnnrl;
       SETn( left * right );
@@ -788,7 +804,7 @@ PP(pp_multiply)
 
 PP(pp_divide)
 {
-    dSP; dATARGET; tryAMAGICbin(div,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(div,opASSIGN); 
     {
       dPOPPOPnnrl;
       double value;
@@ -816,7 +832,7 @@ PP(pp_divide)
 
 PP(pp_modulo)
 {
-    dSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
+    djSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
     {
       UV left;
       UV right;
@@ -851,8 +867,8 @@ PP(pp_modulo)
       if (right_neg) {
        /* XXX may warn: unary minus operator applied to unsigned type */
        /* could change -foo to be (~foo)+1 instead     */
-       if (ans <= -(UV)IV_MAX)
-         sv_setiv(TARG, (IV) -ans);
+       if (ans <= ~((UV)IV_MAX)+1)
+         sv_setiv(TARG, ~ans+1);
        else
          sv_setnv(TARG, -(double)ans);
       }
@@ -865,7 +881,7 @@ PP(pp_modulo)
 
 PP(pp_repeat)
 {
-  dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN);
+  djSP; dATARGET; tryAMAGICbin(repeat,opASSIGN);
   {
     register I32 count = POPi;
     if (GIMME == G_ARRAY && op->op_private & OPpREPEAT_DOLIST) {
@@ -921,7 +937,7 @@ PP(pp_repeat)
 
 PP(pp_subtract)
 {
-    dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(subtr,opASSIGN); 
     {
       dPOPTOPnnrl_ul;
       SETn( left - right );
@@ -931,7 +947,7 @@ PP(pp_subtract)
 
 PP(pp_left_shift)
 {
-    dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(lshift,opASSIGN); 
     {
       IBW shift = POPi;
       if (op->op_private & HINT_INTEGER) {
@@ -950,7 +966,7 @@ PP(pp_left_shift)
 
 PP(pp_right_shift)
 {
-    dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(rshift,opASSIGN); 
     {
       IBW shift = POPi;
       if (op->op_private & HINT_INTEGER) {
@@ -969,7 +985,7 @@ PP(pp_right_shift)
 
 PP(pp_lt)
 {
-    dSP; tryAMAGICbinSET(lt,0); 
+    djSP; tryAMAGICbinSET(lt,0); 
     {
       dPOPnv;
       SETs(boolSV(TOPn < value));
@@ -979,7 +995,7 @@ PP(pp_lt)
 
 PP(pp_gt)
 {
-    dSP; tryAMAGICbinSET(gt,0); 
+    djSP; tryAMAGICbinSET(gt,0); 
     {
       dPOPnv;
       SETs(boolSV(TOPn > value));
@@ -989,7 +1005,7 @@ PP(pp_gt)
 
 PP(pp_le)
 {
-    dSP; tryAMAGICbinSET(le,0); 
+    djSP; tryAMAGICbinSET(le,0); 
     {
       dPOPnv;
       SETs(boolSV(TOPn <= value));
@@ -999,7 +1015,7 @@ PP(pp_le)
 
 PP(pp_ge)
 {
-    dSP; tryAMAGICbinSET(ge,0); 
+    djSP; tryAMAGICbinSET(ge,0); 
     {
       dPOPnv;
       SETs(boolSV(TOPn >= value));
@@ -1009,7 +1025,7 @@ PP(pp_ge)
 
 PP(pp_ne)
 {
-    dSP; tryAMAGICbinSET(ne,0); 
+    djSP; tryAMAGICbinSET(ne,0); 
     {
       dPOPnv;
       SETs(boolSV(TOPn != value));
@@ -1019,7 +1035,7 @@ PP(pp_ne)
 
 PP(pp_ncmp)
 {
-    dSP; dTARGET; tryAMAGICbin(ncmp,0); 
+    djSP; dTARGET; tryAMAGICbin(ncmp,0); 
     {
       dPOPTOPnnrl;
       I32 value;
@@ -1041,7 +1057,7 @@ PP(pp_ncmp)
 
 PP(pp_slt)
 {
-    dSP; tryAMAGICbinSET(slt,0); 
+    djSP; tryAMAGICbinSET(slt,0); 
     {
       dPOPTOPssrl;
       int cmp = ((op->op_private & OPpLOCALE)
@@ -1054,7 +1070,7 @@ PP(pp_slt)
 
 PP(pp_sgt)
 {
-    dSP; tryAMAGICbinSET(sgt,0); 
+    djSP; tryAMAGICbinSET(sgt,0); 
     {
       dPOPTOPssrl;
       int cmp = ((op->op_private & OPpLOCALE)
@@ -1067,7 +1083,7 @@ PP(pp_sgt)
 
 PP(pp_sle)
 {
-    dSP; tryAMAGICbinSET(sle,0); 
+    djSP; tryAMAGICbinSET(sle,0); 
     {
       dPOPTOPssrl;
       int cmp = ((op->op_private & OPpLOCALE)
@@ -1080,7 +1096,7 @@ PP(pp_sle)
 
 PP(pp_sge)
 {
-    dSP; tryAMAGICbinSET(sge,0); 
+    djSP; tryAMAGICbinSET(sge,0); 
     {
       dPOPTOPssrl;
       int cmp = ((op->op_private & OPpLOCALE)
@@ -1093,7 +1109,7 @@ PP(pp_sge)
 
 PP(pp_seq)
 {
-    dSP; tryAMAGICbinSET(seq,0); 
+    djSP; tryAMAGICbinSET(seq,0); 
     {
       dPOPTOPssrl;
       SETs(boolSV(sv_eq(left, right)));
@@ -1103,7 +1119,7 @@ PP(pp_seq)
 
 PP(pp_sne)
 {
-    dSP; tryAMAGICbinSET(sne,0); 
+    djSP; tryAMAGICbinSET(sne,0); 
     {
       dPOPTOPssrl;
       SETs(boolSV(!sv_eq(left, right)));
@@ -1113,7 +1129,7 @@ PP(pp_sne)
 
 PP(pp_scmp)
 {
-    dSP; dTARGET;  tryAMAGICbin(scmp,0);
+    djSP; dTARGET;  tryAMAGICbin(scmp,0);
     {
       dPOPTOPssrl;
       int cmp = ((op->op_private & OPpLOCALE)
@@ -1126,7 +1142,7 @@ PP(pp_scmp)
 
 PP(pp_bit_and)
 {
-    dSP; dATARGET; tryAMAGICbin(band,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(band,opASSIGN); 
     {
       dPOPTOPssrl;
       if (SvNIOKp(left) || SvNIOKp(right)) {
@@ -1149,7 +1165,7 @@ PP(pp_bit_and)
 
 PP(pp_bit_xor)
 {
-    dSP; dATARGET; tryAMAGICbin(bxor,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(bxor,opASSIGN); 
     {
       dPOPTOPssrl;
       if (SvNIOKp(left) || SvNIOKp(right)) {
@@ -1172,7 +1188,7 @@ PP(pp_bit_xor)
 
 PP(pp_bit_or)
 {
-    dSP; dATARGET; tryAMAGICbin(bor,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(bor,opASSIGN); 
     {
       dPOPTOPssrl;
       if (SvNIOKp(left) || SvNIOKp(right)) {
@@ -1195,7 +1211,7 @@ PP(pp_bit_or)
 
 PP(pp_negate)
 {
-    dSP; dTARGET; tryAMAGICun(neg);
+    djSP; dTARGET; tryAMAGICun(neg);
     {
        dTOPss;
        if (SvGMAGICAL(sv))
@@ -1228,7 +1244,7 @@ PP(pp_negate)
 PP(pp_not)
 {
 #ifdef OVERLOAD
-    dSP; tryAMAGICunSET(not);
+    djSP; tryAMAGICunSET(not);
 #endif /* OVERLOAD */
     *stack_sp = boolSV(!SvTRUE(*stack_sp));
     return NORMAL;
@@ -1236,7 +1252,7 @@ PP(pp_not)
 
 PP(pp_complement)
 {
-    dSP; dTARGET; tryAMAGICun(compl); 
+    djSP; dTARGET; tryAMAGICun(compl); 
     {
       dTOPss;
       if (SvNIOKp(sv)) {
@@ -1279,7 +1295,7 @@ PP(pp_complement)
 
 PP(pp_i_multiply)
 {
-    dSP; dATARGET; tryAMAGICbin(mult,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(mult,opASSIGN); 
     {
       dPOPTOPiirl;
       SETi( left * right );
@@ -1289,7 +1305,7 @@ PP(pp_i_multiply)
 
 PP(pp_i_divide)
 {
-    dSP; dATARGET; tryAMAGICbin(div,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(div,opASSIGN); 
     {
       dPOPiv;
       if (value == 0)
@@ -1302,7 +1318,7 @@ PP(pp_i_divide)
 
 PP(pp_i_modulo)
 {
-    dSP; dATARGET; tryAMAGICbin(mod,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(mod,opASSIGN); 
     {
       dPOPTOPiirl;
       if (!right)
@@ -1314,7 +1330,7 @@ PP(pp_i_modulo)
 
 PP(pp_i_add)
 {
-    dSP; dATARGET; tryAMAGICbin(add,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(add,opASSIGN); 
     {
       dPOPTOPiirl;
       SETi( left + right );
@@ -1324,7 +1340,7 @@ PP(pp_i_add)
 
 PP(pp_i_subtract)
 {
-    dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN); 
+    djSP; dATARGET; tryAMAGICbin(subtr,opASSIGN); 
     {
       dPOPTOPiirl;
       SETi( left - right );
@@ -1334,7 +1350,7 @@ PP(pp_i_subtract)
 
 PP(pp_i_lt)
 {
-    dSP; tryAMAGICbinSET(lt,0); 
+    djSP; tryAMAGICbinSET(lt,0); 
     {
       dPOPTOPiirl;
       SETs(boolSV(left < right));
@@ -1344,7 +1360,7 @@ PP(pp_i_lt)
 
 PP(pp_i_gt)
 {
-    dSP; tryAMAGICbinSET(gt,0); 
+    djSP; tryAMAGICbinSET(gt,0); 
     {
       dPOPTOPiirl;
       SETs(boolSV(left > right));
@@ -1354,7 +1370,7 @@ PP(pp_i_gt)
 
 PP(pp_i_le)
 {
-    dSP; tryAMAGICbinSET(le,0); 
+    djSP; tryAMAGICbinSET(le,0); 
     {
       dPOPTOPiirl;
       SETs(boolSV(left <= right));
@@ -1364,7 +1380,7 @@ PP(pp_i_le)
 
 PP(pp_i_ge)
 {
-    dSP; tryAMAGICbinSET(ge,0); 
+    djSP; tryAMAGICbinSET(ge,0); 
     {
       dPOPTOPiirl;
       SETs(boolSV(left >= right));
@@ -1374,7 +1390,7 @@ PP(pp_i_ge)
 
 PP(pp_i_eq)
 {
-    dSP; tryAMAGICbinSET(eq,0); 
+    djSP; tryAMAGICbinSET(eq,0); 
     {
       dPOPTOPiirl;
       SETs(boolSV(left == right));
@@ -1384,7 +1400,7 @@ PP(pp_i_eq)
 
 PP(pp_i_ne)
 {
-    dSP; tryAMAGICbinSET(ne,0); 
+    djSP; tryAMAGICbinSET(ne,0); 
     {
       dPOPTOPiirl;
       SETs(boolSV(left != right));
@@ -1394,7 +1410,7 @@ PP(pp_i_ne)
 
 PP(pp_i_ncmp)
 {
-    dSP; dTARGET; tryAMAGICbin(ncmp,0); 
+    djSP; dTARGET; tryAMAGICbin(ncmp,0); 
     {
       dPOPTOPiirl;
       I32 value;
@@ -1412,7 +1428,7 @@ PP(pp_i_ncmp)
 
 PP(pp_i_negate)
 {
-    dSP; dTARGET; tryAMAGICun(neg);
+    djSP; dTARGET; tryAMAGICun(neg);
     SETi(-TOPi);
     RETURN;
 }
@@ -1421,7 +1437,7 @@ PP(pp_i_negate)
 
 PP(pp_atan2)
 {
-    dSP; dTARGET; tryAMAGICbin(atan2,0); 
+    djSP; dTARGET; tryAMAGICbin(atan2,0); 
     {
       dPOPTOPnnrl;
       SETn(atan2(left, right));
@@ -1431,7 +1447,7 @@ PP(pp_atan2)
 
 PP(pp_sin)
 {
-    dSP; dTARGET; tryAMAGICun(sin);
+    djSP; dTARGET; tryAMAGICun(sin);
     {
       double value;
       value = POPn;
@@ -1443,7 +1459,7 @@ PP(pp_sin)
 
 PP(pp_cos)
 {
-    dSP; dTARGET; tryAMAGICun(cos);
+    djSP; dTARGET; tryAMAGICun(cos);
     {
       double value;
       value = POPn;
@@ -1455,7 +1471,7 @@ PP(pp_cos)
 
 PP(pp_rand)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     double value;
     if (MAXARG < 1)
        value = 1.0;
@@ -1486,7 +1502,7 @@ PP(pp_rand)
 
 PP(pp_srand)
 {
-    dSP;
+    djSP;
     UV anum;
     if (MAXARG < 1)
        anum = seed();
@@ -1499,7 +1515,7 @@ PP(pp_srand)
 }
 
 static U32
-seed()
+seed(void)
 {
     /*
      * This is really just a quick hack which grabs various garbage
@@ -1523,6 +1539,7 @@ seed()
 #define   SEED_C3      269
 #define   SEED_C5      26107
 
+    dTHR;
     U32 u;
 #ifdef VMS
 #  include <starlet.h>
@@ -1552,7 +1569,7 @@ seed()
 
 PP(pp_exp)
 {
-    dSP; dTARGET; tryAMAGICun(exp);
+    djSP; dTARGET; tryAMAGICun(exp);
     {
       double value;
       value = POPn;
@@ -1564,7 +1581,7 @@ PP(pp_exp)
 
 PP(pp_log)
 {
-    dSP; dTARGET; tryAMAGICun(log);
+    djSP; dTARGET; tryAMAGICun(log);
     {
       double value;
       value = POPn;
@@ -1580,7 +1597,7 @@ PP(pp_log)
 
 PP(pp_sqrt)
 {
-    dSP; dTARGET; tryAMAGICun(sqrt);
+    djSP; dTARGET; tryAMAGICun(sqrt);
     {
       double value;
       value = POPn;
@@ -1596,7 +1613,7 @@ PP(pp_sqrt)
 
 PP(pp_int)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     {
       double value = TOPn;
       IV iv;
@@ -1624,7 +1641,7 @@ PP(pp_int)
 
 PP(pp_abs)
 {
-    dSP; dTARGET; tryAMAGICun(abs);
+    djSP; dTARGET; tryAMAGICun(abs);
     {
       double value = TOPn;
       IV iv;
@@ -1646,7 +1663,7 @@ PP(pp_abs)
 
 PP(pp_hex)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     char *tmps;
     I32 argtype;
 
@@ -1657,7 +1674,7 @@ PP(pp_hex)
 
 PP(pp_oct)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     UV value;
     I32 argtype;
     char *tmps;
@@ -1679,14 +1696,14 @@ PP(pp_oct)
 
 PP(pp_length)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     SETi( sv_len(TOPs) );
     RETURN;
 }
 
 PP(pp_substr)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     SV *sv;
     I32 len;
     STRLEN curlen;
@@ -1773,7 +1790,7 @@ PP(pp_substr)
 
 PP(pp_vec)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     register I32 size = POPi;
     register I32 offset = POPi;
     register SV *src = POPs;
@@ -1847,7 +1864,7 @@ PP(pp_vec)
 
 PP(pp_index)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     SV *big;
     SV *little;
     I32 offset;
@@ -1879,7 +1896,7 @@ PP(pp_index)
 
 PP(pp_rindex)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     SV *big;
     SV *little;
     STRLEN blen;
@@ -1916,7 +1933,7 @@ PP(pp_rindex)
 
 PP(pp_sprintf)
 {
-    dSP; dMARK; dORIGMARK; dTARGET;
+    djSP; dMARK; dORIGMARK; dTARGET;
 #ifdef USE_LOCALE_NUMERIC
     if (op->op_private & OPpLOCALE)
        SET_NUMERIC_LOCAL();
@@ -1932,7 +1949,7 @@ PP(pp_sprintf)
 
 PP(pp_ord)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     I32 value;
     char *tmps;
 
@@ -1951,7 +1968,7 @@ PP(pp_ord)
 
 PP(pp_chr)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     char *tmps;
 
     (void)SvUPGRADE(TARG,SVt_PV);
@@ -1967,7 +1984,7 @@ PP(pp_chr)
 
 PP(pp_crypt)
 {
-    dSP; dTARGET; dPOPTOPssrl;
+    djSP; dTARGET; dPOPTOPssrl;
 #ifdef HAS_CRYPT
     char *tmps = SvPV(left, na);
 #ifdef FCRYPT
@@ -1985,7 +2002,7 @@ PP(pp_crypt)
 
 PP(pp_ucfirst)
 {
-    dSP;
+    djSP;
     SV *sv = TOPs;
     register char *s;
 
@@ -2011,7 +2028,7 @@ PP(pp_ucfirst)
 
 PP(pp_lcfirst)
 {
-    dSP;
+    djSP;
     SV *sv = TOPs;
     register char *s;
 
@@ -2038,7 +2055,7 @@ PP(pp_lcfirst)
 
 PP(pp_uc)
 {
-    dSP;
+    djSP;
     SV *sv = TOPs;
     register char *s;
     STRLEN len;
@@ -2070,7 +2087,7 @@ PP(pp_uc)
 
 PP(pp_lc)
 {
-    dSP;
+    djSP;
     SV *sv = TOPs;
     register char *s;
     STRLEN len;
@@ -2102,7 +2119,7 @@ PP(pp_lc)
 
 PP(pp_quotemeta)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     SV *sv = TOPs;
     STRLEN len;
     register char *s = SvPV(sv,len);
@@ -2131,7 +2148,7 @@ PP(pp_quotemeta)
 
 PP(pp_aslice)
 {
-    dSP; dMARK; dORIGMARK;
+    djSP; dMARK; dORIGMARK;
     register SV** svp;
     register AV* av = (AV*)POPs;
     register I32 lval = op->op_flags & OPf_MOD;
@@ -2176,13 +2193,15 @@ PP(pp_aslice)
 
 PP(pp_each)
 {
-    dSP; dTARGET;
+    djSP; dTARGET;
     HV *hash = (HV*)POPs;
     HE *entry;
     I32 gimme = GIMME_V;
+    I32 realhv = (SvTYPE(hash) == SVt_PVHV);
     
     PUTBACK;
-    entry = hv_iternext(hash);         /* might clobber stack_sp */
+    /* might clobber stack_sp */
+    entry = realhv ? hv_iternext(hash) : avhv_iternext((AV*)hash);
     SPAGAIN;
 
     EXTEND(SP, 2);
@@ -2190,7 +2209,9 @@ PP(pp_each)
        PUSHs(hv_iterkeysv(entry));     /* won't clobber stack_sp */
        if (gimme == G_ARRAY) {
            PUTBACK;
-           sv_setsv(TARG, hv_iterval(hash, entry));  /* might hit stack_sp */
+           /* might clobber stack_sp */
+           sv_setsv(TARG, realhv ?
+                    hv_iterval(hash, entry) : avhv_iterval((AV*)hash, entry));
            SPAGAIN;
            PUSHs(TARG);
        }
@@ -2213,7 +2234,7 @@ PP(pp_keys)
 
 PP(pp_delete)
 {
-    dSP;
+    djSP;
     I32 gimme = GIMME_V;
     I32 discard = (gimme == G_VOID) ? G_DISCARD : 0;
     SV *sv;
@@ -2221,11 +2242,16 @@ PP(pp_delete)
 
     if (op->op_private & OPpSLICE) {
        dMARK; dORIGMARK;
+       U32 hvtype;
        hv = (HV*)POPs;
-       if (SvTYPE(hv) != SVt_PVHV)
-           DIE("Not a HASH reference");
+       hvtype = SvTYPE(hv);
        while (++MARK <= SP) {
-           sv = hv_delete_ent(hv, *MARK, discard, 0);
+           if (hvtype == SVt_PVHV)
+               sv = hv_delete_ent(hv, *MARK, discard, 0);
+           else if (hvtype == SVt_PVAV)
+               sv = avhv_delete_ent((AV*)hv, *MARK, discard, 0);
+           else
+               DIE("Not a HASH reference");
            *MARK = sv ? sv : &sv_undef;
        }
        if (discard)
@@ -2239,9 +2265,12 @@ PP(pp_delete)
     else {
        SV *keysv = POPs;
        hv = (HV*)POPs;
-       if (SvTYPE(hv) != SVt_PVHV)
+       if (SvTYPE(hv) == SVt_PVHV)
+           sv = hv_delete_ent(hv, keysv, discard, 0);
+       else if (SvTYPE(hv) == SVt_PVAV)
+           sv = avhv_delete_ent((AV*)hv, keysv, discard, 0);
+       else
            DIE("Not a HASH reference");
-       sv = hv_delete_ent(hv, keysv, discard, 0);
        if (!sv)
            sv = &sv_undef;
        if (!discard)
@@ -2252,30 +2281,39 @@ PP(pp_delete)
 
 PP(pp_exists)
 {
-    dSP;
+    djSP;
     SV *tmpsv = POPs;
     HV *hv = (HV*)POPs;
-    STRLEN len;
-    if (SvTYPE(hv) != SVt_PVHV) {
+    if (SvTYPE(hv) == SVt_PVHV) {
+       if (hv_exists_ent(hv, tmpsv, 0))
+           RETPUSHYES;
+    } else if (SvTYPE(hv) == SVt_PVAV) {
+       if (avhv_exists_ent((AV*)hv, tmpsv, 0))
+           RETPUSHYES;
+    } else {
        DIE("Not a HASH reference");
     }
-    if (hv_exists_ent(hv, tmpsv, 0))
-       RETPUSHYES;
     RETPUSHNO;
 }
 
 PP(pp_hslice)
 {
-    dSP; dMARK; dORIGMARK;
+    djSP; dMARK; dORIGMARK;
     register HE *he;
     register HV *hv = (HV*)POPs;
     register I32 lval = op->op_flags & OPf_MOD;
+    I32 realhv = (SvTYPE(hv) == SVt_PVHV);
 
-    if (SvTYPE(hv) == SVt_PVHV) {
+    if (realhv || SvTYPE(hv) == SVt_PVAV) {
        while (++MARK <= SP) {
            SV *keysv = *MARK;
-
-           he = hv_fetch_ent(hv, keysv, lval, 0);
+           SV **svp;
+           if (realhv) {
+               he = hv_fetch_ent(hv, keysv, lval, 0);
+               svp = he ? &HeVAL(he) : 0;
+           } else {
+               svp = avhv_fetch_ent((AV*)hv, keysv, lval, 0);
+           }
            if (lval) {
                if (!he || HeVAL(he) == &sv_undef)
                    DIE(no_helem, SvPV(keysv, na));
@@ -2297,7 +2335,7 @@ PP(pp_hslice)
 
 PP(pp_list)
 {
-    dSP; dMARK;
+    djSP; dMARK;
     if (GIMME != G_ARRAY) {
        if (++MARK <= SP)
            *MARK = *SP;                /* unwanted list, return last item */
@@ -2310,7 +2348,7 @@ PP(pp_list)
 
 PP(pp_lslice)
 {
-    dSP;
+    djSP;
     SV **lastrelem = stack_sp;
     SV **lastlelem = stack_base + POPMARK;
     SV **firstlelem = stack_base + POPMARK + 1;
@@ -2368,7 +2406,7 @@ PP(pp_lslice)
 
 PP(pp_anonlist)
 {
-    dSP; dMARK; dORIGMARK;
+    djSP; dMARK; dORIGMARK;
     I32 items = SP - MARK;
     SV *av = sv_2mortal((SV*)av_make(items, MARK+1));
     SP = ORIGMARK;             /* av_make() might realloc stack_sp */
@@ -2378,7 +2416,7 @@ PP(pp_anonlist)
 
 PP(pp_anonhash)
 {
-    dSP; dMARK; dORIGMARK;
+    djSP; dMARK; dORIGMARK;
     HV* hv = (HV*)sv_2mortal((SV*)newHV());
 
     while (MARK < SP) {
@@ -2397,7 +2435,7 @@ PP(pp_anonhash)
 
 PP(pp_splice)
 {
-    dSP; dMARK; dORIGMARK;
+    djSP; dMARK; dORIGMARK;
     register AV *ary = (AV*)*++MARK;
     register SV **src;
     register SV **dst;
@@ -2592,7 +2630,7 @@ PP(pp_splice)
 
 PP(pp_push)
 {
-    dSP; dMARK; dORIGMARK; dTARGET;
+    djSP; dMARK; dORIGMARK; dTARGET;
     register AV *ary = (AV*)*++MARK;
     register SV *sv = &sv_undef;
 
@@ -2609,7 +2647,7 @@ PP(pp_push)
 
 PP(pp_pop)
 {
-    dSP;
+    djSP;
     AV *av = (AV*)POPs;
     SV *sv = av_pop(av);
     if (!SvIMMORTAL(sv) && AvREAL(av))
@@ -2620,7 +2658,7 @@ PP(pp_pop)
 
 PP(pp_shift)
 {
-    dSP;
+    djSP;
     AV *av = (AV*)POPs;
     SV *sv = av_shift(av);
     EXTEND(SP, 1);
@@ -2634,7 +2672,7 @@ PP(pp_shift)
 
 PP(pp_unshift)
 {
-    dSP; dMARK; dORIGMARK; dTARGET;
+    djSP; dMARK; dORIGMARK; dTARGET;
     register AV *ary = (AV*)*++MARK;
     register SV *sv;
     register I32 i = 0;
@@ -2653,7 +2691,7 @@ PP(pp_unshift)
 
 PP(pp_reverse)
 {
-    dSP; dMARK;
+    djSP; dMARK;
     register SV *tmp;
     SV **oldsp = SP;
 
@@ -2676,7 +2714,7 @@ PP(pp_reverse)
        if (SP - MARK > 1)
            do_join(TARG, &sv_no, MARK, SP);
        else
-           sv_setsv(TARG, (SP > MARK) ? *SP : GvSV(defgv));
+           sv_setsv(TARG, (SP > MARK) ? *SP : DEFSV);
        up = SvPV_force(TARG, len);
        if (len > 1) {
            down = SvPVX(TARG) + len - 1;
@@ -2694,9 +2732,7 @@ PP(pp_reverse)
 }
 
 static SV      *
-mul128(sv, m)
-     SV             *sv;
-     U8              m;
+mul128(SV *sv, U8 m)
 {
   STRLEN          len;
   char           *s = SvPV(sv, len);
@@ -2704,11 +2740,11 @@ mul128(sv, m)
   U32             i = 0;
 
   if (!strnEQ(s, "0000", 4)) {  /* need to grow sv */
-    SV             *new = newSVpv("0000000000", 10);
+    SV             *New = newSVpv("0000000000", 10);
 
-    sv_catsv(new, sv);
+    sv_catsv(New, sv);
     SvREFCNT_dec(sv);          /* free old sv */
-    sv = new;
+    sv = New;
     s = SvPV(sv, len);
   }
   t = s + len - 1;
@@ -2726,7 +2762,7 @@ mul128(sv, m)
 
 PP(pp_unpack)
 {
-    dSP;
+    djSP;
     dPOPPOPssrl;
     SV **oldsp = sp;
     I32 gimme = GIMME_V;
@@ -3364,10 +3400,10 @@ PP(pp_unpack)
                        d = (*s++ - ' ') & 077;
                    else
                        d = 0;
-                   hunk[0] = a << 2 | b >> 4;
-                   hunk[1] = b << 4 | c >> 2;
-                   hunk[2] = c << 6 | d;
-                   sv_catpvn(sv, hunk, len > 3 ? 3 : len);
+                   hunk[0] = (a << 2) | (b >> 4);
+                   hunk[1] = (b << 4) | (c >> 2);
+                   hunk[2] = (c << 6) | d;
+                   sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
                    len -= 3;
                }
                if (*s == '\n')
@@ -3418,10 +3454,7 @@ PP(pp_unpack)
 }
 
 static void
-doencodes(sv, s, len)
-register SV *sv;
-register char *s;
-register I32 len;
+doencodes(register SV *sv, register char *s, register I32 len)
 {
     char hunk[5];
 
@@ -3430,8 +3463,8 @@ register I32 len;
     hunk[4] = '\0';
     while (len > 0) {
        hunk[0] = ' ' + (077 & (*s >> 2));
-       hunk[1] = ' ' + (077 & ((*s << 4) & 060 | (s[1] >> 4) & 017));
-       hunk[2] = ' ' + (077 & ((s[1] << 2) & 074 | (s[2] >> 6) & 03));
+       hunk[1] = ' ' + (077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)));
+       hunk[2] = ' ' + (077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)));
        hunk[3] = ' ' + (077 & (s[2] & 077));
        sv_catpvn(sv, hunk, 4);
        s += 3;
@@ -3445,9 +3478,7 @@ register I32 len;
 }
 
 static SV      *
-is_an_int(s, l)
-     char           *s;
-     STRLEN          l;
+is_an_int(char *s, STRLEN l)
 {
   SV             *result = newSVpv("", l);
   char           *result_c = SvPV(result, na); /* convenience */
@@ -3495,9 +3526,9 @@ is_an_int(s, l)
 }
 
 static int
-div128(pnum, done)
-     SV             *pnum;                 /* must be '\0' terminated */
-     bool           *done;
+div128(SV *pnum, bool *done)
+                                           /* must be '\0' terminated */
+                          
 {
   STRLEN          len;
   char           *s = SvPV(pnum, len);
@@ -3525,7 +3556,7 @@ div128(pnum, done)
 
 PP(pp_pack)
 {
-    dSP; dMARK; dORIGMARK; dTARGET;
+    djSP; dMARK; dORIGMARK; dTARGET;
     register SV *cat = TARG;
     register I32 items;
     STRLEN fromlen;
@@ -3991,7 +4022,7 @@ PP(pp_pack)
 
 PP(pp_split)
 {
-    dSP; dTARG;
+    djSP; dTARG;
     AV *ary;
     register I32 limit = POPi;                 /* note, negative is forever */
     SV *sv = POPs;
@@ -4028,7 +4059,11 @@ PP(pp_split)
     if (pm->op_pmreplroot)
        ary = GvAVn((GV*)pm->op_pmreplroot);
     else if (gimme != G_ARRAY)
+#ifdef USE_THREADS
+       ary = (AV*)curpad[0];
+#else
        ary = GvAVn(defgv);
+#endif /* USE_THREADS */
     else
        ary = Nullav;
     if (ary && (gimme != G_ARRAY || (pm->op_pmflags & PMf_ONCE))) {
@@ -4100,10 +4135,12 @@ PP(pp_split)
            s = m;
        }
     }
-    else if (pm->op_pmshort && !rx->nparens) {
-       i = SvCUR(pm->op_pmshort);
-       if (i == 1) {
-           i = *SvPVX(pm->op_pmshort);
+    else if (rx->check_substr && !rx->nparens 
+            && (rx->reganch & ROPT_CHECK_ALL)
+            && !(rx->reganch & ROPT_ANCH)) {
+       i = SvCUR(rx->check_substr);
+       if (i == 1 && !SvTAIL(rx->check_substr)) {
+           i = *SvPVX(rx->check_substr);
            while (--limit) {
                /*SUPPRESS 530*/
                for (m = s; m < strend && *m != i; m++) ;
@@ -4121,7 +4158,7 @@ PP(pp_split)
 #ifndef lint
            while (s < strend && --limit &&
              (m=fbm_instr((unsigned char*)s, (unsigned char*)strend,
-                   pm->op_pmshort)) )
+                   rx->check_substr)) )
 #endif
            {
                dstr = NEWSV(31, m-s);
@@ -4136,9 +4173,9 @@ PP(pp_split)
     else {
        maxiters += (strend - s) * rx->nparens;
        while (s < strend && --limit &&
-              pregexec(rx, s, strend, orig, 1, Nullsv, TRUE))
+              regexec_flags(rx, s, strend, orig, 1, Nullsv, NULL, 0))
        {
-           TAINT_IF(rx->exec_tainted);
+           TAINT_IF(RX_MATCH_TAINTED(rx));
            if (rx->subbase
              && rx->subbase != orig) {
                m = s;
@@ -4215,3 +4252,71 @@ PP(pp_split)
     RETPUSHUNDEF;
 }
 
+#ifdef USE_THREADS
+void
+unlock_condpair(void *svv)
+{
+    dTHR;
+    MAGIC *mg = mg_find((SV*)svv, 'm');
+    
+    if (!mg)
+       croak("panic: unlock_condpair unlocking non-mutex");
+    MUTEX_LOCK(MgMUTEXP(mg));
+    if (MgOWNER(mg) != thr)
+       croak("panic: unlock_condpair unlocking mutex that we don't own");
+    MgOWNER(mg) = 0;
+    COND_SIGNAL(MgOWNERCONDP(mg));
+    DEBUG_L(PerlIO_printf(PerlIO_stderr(), "0x%lx: unlock 0x%lx\n",
+                         (unsigned long)thr, (unsigned long)svv);)
+    MUTEX_UNLOCK(MgMUTEXP(mg));
+}
+#endif /* USE_THREADS */
+
+PP(pp_lock)
+{
+    djSP;
+    dTOPss;
+    SV *retsv = sv;
+#ifdef USE_THREADS
+    MAGIC *mg;
+    
+    if (SvROK(sv))
+       sv = SvRV(sv);
+
+    mg = condpair_magic(sv);
+    MUTEX_LOCK(MgMUTEXP(mg));
+    if (MgOWNER(mg) == thr)
+       MUTEX_UNLOCK(MgMUTEXP(mg));
+    else {
+       while (MgOWNER(mg))
+           COND_WAIT(MgOWNERCONDP(mg), MgMUTEXP(mg));
+       MgOWNER(mg) = thr;
+       DEBUG_L(PerlIO_printf(PerlIO_stderr(), "0x%lx: pp_lock lock 0x%lx\n",
+                             (unsigned long)thr, (unsigned long)sv);)
+       MUTEX_UNLOCK(MgMUTEXP(mg));
+       SvREFCNT_inc(sv);       /* keep alive until magic_mutexfree */
+       save_destructor(unlock_condpair, sv);
+    }
+#endif /* USE_THREADS */
+    if (SvTYPE(retsv) == SVt_PVAV || SvTYPE(retsv) == SVt_PVHV
+       || SvTYPE(retsv) == SVt_PVCV) {
+       retsv = refto(retsv);
+    }
+    SETs(retsv);
+    RETURN;
+}
+
+PP(pp_threadsv)
+{
+    djSP;
+#ifdef USE_THREADS
+    EXTEND(sp, 1);
+    if (op->op_private & OPpLVAL_INTRO)
+       PUSHs(*save_threadsv(op->op_targ));
+    else
+       PUSHs(*av_fetch(thr->threadsv, op->op_targ, FALSE));
+    RETURN;
+#else
+    DIE("tried to access per-thread data in non-threaded perl");
+#endif /* USE_THREADS */
+}