Die when integer overflow condition is detected in division under
[p5sagit/p5-mst-13.2.git] / pp.c
1 /*    pp.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4  *    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10
11 /*
12  * "It's a big house this, and very peculiar.  Always a bit more to discover,
13  * and no knowing what you'll find around a corner.  And Elves, sir!" --Samwise
14  */
15
16 /* This file contains general pp ("push/pop") functions that execute the
17  * opcodes that make up a perl program. A typical pp function expects to
18  * find its arguments on the stack, and usually pushes its results onto
19  * the stack, hence the 'pp' terminology. Each OP structure contains
20  * a pointer to the relevant pp_foo() function.
21  */
22
23 #include "EXTERN.h"
24 #define PERL_IN_PP_C
25 #include "perl.h"
26 #include "keywords.h"
27
28 #include "reentr.h"
29
30 /* XXX I can't imagine anyone who doesn't have this actually _needs_
31    it, since pid_t is an integral type.
32    --AD  2/20/1998
33 */
34 #ifdef NEED_GETPID_PROTO
35 extern Pid_t getpid (void);
36 #endif
37
38 /*
39  * Some BSDs and Cygwin default to POSIX math instead of IEEE.
40  * This switches them over to IEEE.
41  */
42 #if defined(LIBM_LIB_VERSION)
43     _LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
44 #endif
45
46 /* variations on pp_null */
47
48 PP(pp_stub)
49 {
50     dVAR;
51     dSP;
52     if (GIMME_V == G_SCALAR)
53         XPUSHs(&PL_sv_undef);
54     RETURN;
55 }
56
57 /* Pushy stuff. */
58
59 PP(pp_padav)
60 {
61     dVAR; dSP; dTARGET;
62     I32 gimme;
63     if (PL_op->op_private & OPpLVAL_INTRO)
64         SAVECLEARSV(PAD_SVl(PL_op->op_targ));
65     EXTEND(SP, 1);
66     if (PL_op->op_flags & OPf_REF) {
67         PUSHs(TARG);
68         RETURN;
69     } else if (LVRET) {
70         if (GIMME == G_SCALAR)
71             Perl_croak(aTHX_ "Can't return array to lvalue scalar context");
72         PUSHs(TARG);
73         RETURN;
74     }
75     gimme = GIMME_V;
76     if (gimme == G_ARRAY) {
77         const I32 maxarg = AvFILL((AV*)TARG) + 1;
78         EXTEND(SP, maxarg);
79         if (SvMAGICAL(TARG)) {
80             U32 i;
81             for (i=0; i < (U32)maxarg; i++) {
82                 SV * const * const svp = av_fetch((AV*)TARG, i, FALSE);
83                 SP[i+1] = (svp) ? *svp : &PL_sv_undef;
84             }
85         }
86         else {
87             Copy(AvARRAY((AV*)TARG), SP+1, maxarg, SV*);
88         }
89         SP += maxarg;
90     }
91     else if (gimme == G_SCALAR) {
92         SV* const sv = sv_newmortal();
93         const I32 maxarg = AvFILL((AV*)TARG) + 1;
94         sv_setiv(sv, maxarg);
95         PUSHs(sv);
96     }
97     RETURN;
98 }
99
100 PP(pp_padhv)
101 {
102     dVAR; dSP; dTARGET;
103     I32 gimme;
104
105     XPUSHs(TARG);
106     if (PL_op->op_private & OPpLVAL_INTRO)
107         SAVECLEARSV(PAD_SVl(PL_op->op_targ));
108     if (PL_op->op_flags & OPf_REF)
109         RETURN;
110     else if (LVRET) {
111         if (GIMME == G_SCALAR)
112             Perl_croak(aTHX_ "Can't return hash to lvalue scalar context");
113         RETURN;
114     }
115     gimme = GIMME_V;
116     if (gimme == G_ARRAY) {
117         RETURNOP(do_kv());
118     }
119     else if (gimme == G_SCALAR) {
120         SV* const sv = Perl_hv_scalar(aTHX_ (HV*)TARG);
121         SETs(sv);
122     }
123     RETURN;
124 }
125
126 /* Translations. */
127
128 PP(pp_rv2gv)
129 {
130     dVAR; dSP; dTOPss;
131
132     if (SvROK(sv)) {
133       wasref:
134         tryAMAGICunDEREF(to_gv);
135
136         sv = SvRV(sv);
137         if (SvTYPE(sv) == SVt_PVIO) {
138             GV * const gv = (GV*) sv_newmortal();
139             gv_init(gv, 0, "", 0, 0);
140             GvIOp(gv) = (IO *)sv;
141             (void)SvREFCNT_inc(sv);
142             sv = (SV*) gv;
143         }
144         else if (SvTYPE(sv) != SVt_PVGV)
145             DIE(aTHX_ "Not a GLOB reference");
146     }
147     else {
148         if (SvTYPE(sv) != SVt_PVGV) {
149             if (SvGMAGICAL(sv)) {
150                 mg_get(sv);
151                 if (SvROK(sv))
152                     goto wasref;
153             }
154             if (!SvOK(sv) && sv != &PL_sv_undef) {
155                 /* If this is a 'my' scalar and flag is set then vivify
156                  * NI-S 1999/05/07
157                  */
158                 if (SvREADONLY(sv))
159                     Perl_croak(aTHX_ PL_no_modify);
160                 if (PL_op->op_private & OPpDEREF) {
161                     GV *gv;
162                     if (cUNOP->op_targ) {
163                         STRLEN len;
164                         SV * const namesv = PAD_SV(cUNOP->op_targ);
165                         const char * const name = SvPV(namesv, len);
166                         gv = (GV*)newSV(0);
167                         gv_init(gv, CopSTASH(PL_curcop), name, len, 0);
168                     }
169                     else {
170                         const char * const name = CopSTASHPV(PL_curcop);
171                         gv = newGVgen(name);
172                     }
173                     if (SvTYPE(sv) < SVt_RV)
174                         sv_upgrade(sv, SVt_RV);
175                     if (SvPVX_const(sv)) {
176                         SvPV_free(sv);
177                         SvLEN_set(sv, 0);
178                         SvCUR_set(sv, 0);
179                     }
180                     SvRV_set(sv, (SV*)gv);
181                     SvROK_on(sv);
182                     SvSETMAGIC(sv);
183                     goto wasref;
184                 }
185                 if (PL_op->op_flags & OPf_REF ||
186                     PL_op->op_private & HINT_STRICT_REFS)
187                     DIE(aTHX_ PL_no_usym, "a symbol");
188                 if (ckWARN(WARN_UNINITIALIZED))
189                     report_uninit(sv);
190                 RETSETUNDEF;
191             }
192             if ((PL_op->op_flags & OPf_SPECIAL) &&
193                 !(PL_op->op_flags & OPf_MOD))
194             {
195                 SV * const temp = (SV*)gv_fetchsv(sv, 0, SVt_PVGV);
196                 if (!temp
197                     && (!is_gv_magical_sv(sv,0)
198                         || !(sv = (SV*)gv_fetchsv(sv, GV_ADD, SVt_PVGV)))) {
199                     RETSETUNDEF;
200                 }
201                 sv = temp;
202             }
203             else {
204                 if (PL_op->op_private & HINT_STRICT_REFS)
205                     DIE(aTHX_ PL_no_symref_sv, sv, "a symbol");
206                 if ((PL_op->op_private & (OPpLVAL_INTRO|OPpDONT_INIT_GV))
207                     == OPpDONT_INIT_GV) {
208                     /* We are the target of a coderef assignment.  Return
209                        the scalar unchanged, and let pp_sasssign deal with
210                        things.  */
211                     RETURN;
212                 }
213                 sv = (SV*)gv_fetchsv(sv, GV_ADD, SVt_PVGV);
214             }
215         }
216     }
217     if (PL_op->op_private & OPpLVAL_INTRO)
218         save_gp((GV*)sv, !(PL_op->op_flags & OPf_SPECIAL));
219     SETs(sv);
220     RETURN;
221 }
222
223 PP(pp_rv2sv)
224 {
225     dVAR; dSP; dTOPss;
226     GV *gv = NULL;
227
228     if (SvROK(sv)) {
229       wasref:
230         tryAMAGICunDEREF(to_sv);
231
232         sv = SvRV(sv);
233         switch (SvTYPE(sv)) {
234         case SVt_PVAV:
235         case SVt_PVHV:
236         case SVt_PVCV:
237             DIE(aTHX_ "Not a SCALAR reference");
238         }
239     }
240     else {
241         gv = (GV*)sv;
242
243         if (SvTYPE(gv) != SVt_PVGV) {
244             if (SvGMAGICAL(sv)) {
245                 mg_get(sv);
246                 if (SvROK(sv))
247                     goto wasref;
248             }
249             if (PL_op->op_private & HINT_STRICT_REFS) {
250                 if (SvOK(sv))
251                     DIE(aTHX_ PL_no_symref_sv, sv, "a SCALAR");
252                 else
253                     DIE(aTHX_ PL_no_usym, "a SCALAR");
254             }
255             if (!SvOK(sv)) {
256                 if (PL_op->op_flags & OPf_REF)
257                     DIE(aTHX_ PL_no_usym, "a SCALAR");
258                 if (ckWARN(WARN_UNINITIALIZED))
259                     report_uninit(sv);
260                 RETSETUNDEF;
261             }
262             if ((PL_op->op_flags & OPf_SPECIAL) &&
263                 !(PL_op->op_flags & OPf_MOD))
264             {
265                 gv = (GV*)gv_fetchsv(sv, 0, SVt_PV);
266                 if (!gv
267                     && (!is_gv_magical_sv(sv, 0)
268                         || !(gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV))))
269                 {
270                     RETSETUNDEF;
271                 }
272             }
273             else {
274                 gv = (GV*)gv_fetchsv(sv, GV_ADD, SVt_PV);
275             }
276         }
277         sv = GvSVn(gv);
278     }
279     if (PL_op->op_flags & OPf_MOD) {
280         if (PL_op->op_private & OPpLVAL_INTRO) {
281             if (cUNOP->op_first->op_type == OP_NULL)
282                 sv = save_scalar((GV*)TOPs);
283             else if (gv)
284                 sv = save_scalar(gv);
285             else
286                 Perl_croak(aTHX_ PL_no_localize_ref);
287         }
288         else if (PL_op->op_private & OPpDEREF)
289             vivify_ref(sv, PL_op->op_private & OPpDEREF);
290     }
291     SETs(sv);
292     RETURN;
293 }
294
295 PP(pp_av2arylen)
296 {
297     dVAR; dSP;
298     AV * const av = (AV*)TOPs;
299     SV ** const sv = Perl_av_arylen_p(aTHX_ (AV*)av);
300     if (!*sv) {
301         *sv = newSV(0);
302         sv_upgrade(*sv, SVt_PVMG);
303         sv_magic(*sv, (SV*)av, PERL_MAGIC_arylen, NULL, 0);
304     }
305     SETs(*sv);
306     RETURN;
307 }
308
309 PP(pp_pos)
310 {
311     dVAR; dSP; dTARGET; dPOPss;
312
313     if (PL_op->op_flags & OPf_MOD || LVRET) {
314         if (SvTYPE(TARG) < SVt_PVLV) {
315             sv_upgrade(TARG, SVt_PVLV);
316             sv_magic(TARG, NULL, PERL_MAGIC_pos, NULL, 0);
317         }
318
319         LvTYPE(TARG) = '.';
320         if (LvTARG(TARG) != sv) {
321             if (LvTARG(TARG))
322                 SvREFCNT_dec(LvTARG(TARG));
323             LvTARG(TARG) = SvREFCNT_inc(sv);
324         }
325         PUSHs(TARG);    /* no SvSETMAGIC */
326         RETURN;
327     }
328     else {
329         if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
330             const MAGIC * const mg = mg_find(sv, PERL_MAGIC_regex_global);
331             if (mg && mg->mg_len >= 0) {
332                 I32 i = mg->mg_len;
333                 if (DO_UTF8(sv))
334                     sv_pos_b2u(sv, &i);
335                 PUSHi(i + PL_curcop->cop_arybase);
336                 RETURN;
337             }
338         }
339         RETPUSHUNDEF;
340     }
341 }
342
343 PP(pp_rv2cv)
344 {
345     dVAR; dSP;
346     GV *gv;
347     HV *stash;
348     const I32 flags = (PL_op->op_flags & OPf_SPECIAL)
349         ? 0
350         : ((PL_op->op_private & (OPpLVAL_INTRO|OPpMAY_RETURN_CONSTANT)) == OPpMAY_RETURN_CONSTANT)
351             ? GV_ADD|GV_NOEXPAND
352             : GV_ADD;
353     /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
354     /* (But not in defined().) */
355
356     CV *cv = sv_2cv(TOPs, &stash, &gv, flags);
357     if (cv) {
358         if (CvCLONE(cv))
359             cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
360         if ((PL_op->op_private & OPpLVAL_INTRO)) {
361             if (gv && GvCV(gv) == cv && (gv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), FALSE)))
362                 cv = GvCV(gv);
363             if (!CvLVALUE(cv))
364                 DIE(aTHX_ "Can't modify non-lvalue subroutine call");
365         }
366     }
367     else if ((flags == (GV_ADD|GV_NOEXPAND)) && gv && SvROK(gv)) {
368         cv = (CV*)gv;
369     }    
370     else
371         cv = (CV*)&PL_sv_undef;
372     SETs((SV*)cv);
373     RETURN;
374 }
375
376 PP(pp_prototype)
377 {
378     dVAR; dSP;
379     CV *cv;
380     HV *stash;
381     GV *gv;
382     SV *ret = &PL_sv_undef;
383
384     if (SvPOK(TOPs) && SvCUR(TOPs) >= 7) {
385         const char * const s = SvPVX_const(TOPs);
386         if (strnEQ(s, "CORE::", 6)) {
387             const int code = keyword(s + 6, SvCUR(TOPs) - 6);
388             if (code < 0) {     /* Overridable. */
389 #define MAX_ARGS_OP ((sizeof(I32) - 1) * 2)
390                 int i = 0, n = 0, seen_question = 0;
391                 I32 oa;
392                 char str[ MAX_ARGS_OP * 2 + 2 ]; /* One ';', one '\0' */
393
394                 if (code == -KEY_chop || code == -KEY_chomp
395                         || code == -KEY_exec || code == -KEY_system)
396                     goto set;
397                 while (i < MAXO) {      /* The slow way. */
398                     if (strEQ(s + 6, PL_op_name[i])
399                         || strEQ(s + 6, PL_op_desc[i]))
400                     {
401                         goto found;
402                     }
403                     i++;
404                 }
405                 goto nonesuch;          /* Should not happen... */
406               found:
407                 oa = PL_opargs[i] >> OASHIFT;
408                 while (oa) {
409                     if (oa & OA_OPTIONAL && !seen_question) {
410                         seen_question = 1;
411                         str[n++] = ';';
412                     }
413                     if ((oa & (OA_OPTIONAL - 1)) >= OA_AVREF
414                         && (oa & (OA_OPTIONAL - 1)) <= OA_SCALARREF
415                         /* But globs are already references (kinda) */
416                         && (oa & (OA_OPTIONAL - 1)) != OA_FILEREF
417                     ) {
418                         str[n++] = '\\';
419                     }
420                     str[n++] = ("?$@@%&*$")[oa & (OA_OPTIONAL - 1)];
421                     oa = oa >> 4;
422                 }
423                 str[n++] = '\0';
424                 ret = sv_2mortal(newSVpvn(str, n - 1));
425             }
426             else if (code)              /* Non-Overridable */
427                 goto set;
428             else {                      /* None such */
429               nonesuch:
430                 DIE(aTHX_ "Can't find an opnumber for \"%s\"", s+6);
431             }
432         }
433     }
434     cv = sv_2cv(TOPs, &stash, &gv, 0);
435     if (cv && SvPOK(cv))
436         ret = sv_2mortal(newSVpvn(SvPVX_const(cv), SvCUR(cv)));
437   set:
438     SETs(ret);
439     RETURN;
440 }
441
442 PP(pp_anoncode)
443 {
444     dVAR; dSP;
445     CV* cv = (CV*)PAD_SV(PL_op->op_targ);
446     if (CvCLONE(cv))
447         cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
448     EXTEND(SP,1);
449     PUSHs((SV*)cv);
450     RETURN;
451 }
452
453 PP(pp_srefgen)
454 {
455     dVAR; dSP;
456     *SP = refto(*SP);
457     RETURN;
458 }
459
460 PP(pp_refgen)
461 {
462     dVAR; dSP; dMARK;
463     if (GIMME != G_ARRAY) {
464         if (++MARK <= SP)
465             *MARK = *SP;
466         else
467             *MARK = &PL_sv_undef;
468         *MARK = refto(*MARK);
469         SP = MARK;
470         RETURN;
471     }
472     EXTEND_MORTAL(SP - MARK);
473     while (++MARK <= SP)
474         *MARK = refto(*MARK);
475     RETURN;
476 }
477
478 STATIC SV*
479 S_refto(pTHX_ SV *sv)
480 {
481     dVAR;
482     SV* rv;
483
484     if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') {
485         if (LvTARGLEN(sv))
486             vivify_defelem(sv);
487         if (!(sv = LvTARG(sv)))
488             sv = &PL_sv_undef;
489         else
490             (void)SvREFCNT_inc(sv);
491     }
492     else if (SvTYPE(sv) == SVt_PVAV) {
493         if (!AvREAL((AV*)sv) && AvREIFY((AV*)sv))
494             av_reify((AV*)sv);
495         SvTEMP_off(sv);
496         (void)SvREFCNT_inc(sv);
497     }
498     else if (SvPADTMP(sv) && !IS_PADGV(sv))
499         sv = newSVsv(sv);
500     else {
501         SvTEMP_off(sv);
502         (void)SvREFCNT_inc(sv);
503     }
504     rv = sv_newmortal();
505     sv_upgrade(rv, SVt_RV);
506     SvRV_set(rv, sv);
507     SvROK_on(rv);
508     return rv;
509 }
510
511 PP(pp_ref)
512 {
513     dVAR; dSP; dTARGET;
514     const char *pv;
515     SV * const sv = POPs;
516
517     if (sv)
518         SvGETMAGIC(sv);
519
520     if (!sv || !SvROK(sv))
521         RETPUSHNO;
522
523     pv = sv_reftype(SvRV(sv),TRUE);
524     PUSHp(pv, strlen(pv));
525     RETURN;
526 }
527
528 PP(pp_bless)
529 {
530     dVAR; dSP;
531     HV *stash;
532
533     if (MAXARG == 1)
534         stash = CopSTASH(PL_curcop);
535     else {
536         SV * const ssv = POPs;
537         STRLEN len;
538         const char *ptr;
539
540         if (ssv && !SvGMAGICAL(ssv) && !SvAMAGIC(ssv) && SvROK(ssv))
541             Perl_croak(aTHX_ "Attempt to bless into a reference");
542         ptr = SvPV_const(ssv,len);
543         if (len == 0 && ckWARN(WARN_MISC))
544             Perl_warner(aTHX_ packWARN(WARN_MISC),
545                    "Explicit blessing to '' (assuming package main)");
546         stash = gv_stashpvn(ptr, len, TRUE);
547     }
548
549     (void)sv_bless(TOPs, stash);
550     RETURN;
551 }
552
553 PP(pp_gelem)
554 {
555     dVAR; dSP;
556
557     SV *sv = POPs;
558     const char * const elem = SvPV_nolen_const(sv);
559     GV * const gv = (GV*)POPs;
560     SV * tmpRef = NULL;
561
562     sv = NULL;
563     if (elem) {
564         /* elem will always be NUL terminated.  */
565         const char * const second_letter = elem + 1;
566         switch (*elem) {
567         case 'A':
568             if (strEQ(second_letter, "RRAY"))
569                 tmpRef = (SV*)GvAV(gv);
570             break;
571         case 'C':
572             if (strEQ(second_letter, "ODE"))
573                 tmpRef = (SV*)GvCVu(gv);
574             break;
575         case 'F':
576             if (strEQ(second_letter, "ILEHANDLE")) {
577                 /* finally deprecated in 5.8.0 */
578                 deprecate("*glob{FILEHANDLE}");
579                 tmpRef = (SV*)GvIOp(gv);
580             }
581             else
582                 if (strEQ(second_letter, "ORMAT"))
583                     tmpRef = (SV*)GvFORM(gv);
584             break;
585         case 'G':
586             if (strEQ(second_letter, "LOB"))
587                 tmpRef = (SV*)gv;
588             break;
589         case 'H':
590             if (strEQ(second_letter, "ASH"))
591                 tmpRef = (SV*)GvHV(gv);
592             break;
593         case 'I':
594             if (*second_letter == 'O' && !elem[2])
595                 tmpRef = (SV*)GvIOp(gv);
596             break;
597         case 'N':
598             if (strEQ(second_letter, "AME"))
599                 sv = newSVpvn(GvNAME(gv), GvNAMELEN(gv));
600             break;
601         case 'P':
602             if (strEQ(second_letter, "ACKAGE")) {
603                 const HV * const stash = GvSTASH(gv);
604                 const HEK * const hek = stash ? HvNAME_HEK(stash) : NULL;
605                 sv = hek ? newSVhek(hek) : newSVpvs("__ANON__");
606             }
607             break;
608         case 'S':
609             if (strEQ(second_letter, "CALAR"))
610                 tmpRef = GvSVn(gv);
611             break;
612         }
613     }
614     if (tmpRef)
615         sv = newRV(tmpRef);
616     if (sv)
617         sv_2mortal(sv);
618     else
619         sv = &PL_sv_undef;
620     XPUSHs(sv);
621     RETURN;
622 }
623
624 /* Pattern matching */
625
626 PP(pp_study)
627 {
628     dVAR; dSP; dPOPss;
629     register unsigned char *s;
630     register I32 pos;
631     register I32 ch;
632     register I32 *sfirst;
633     register I32 *snext;
634     STRLEN len;
635
636     if (sv == PL_lastscream) {
637         if (SvSCREAM(sv))
638             RETPUSHYES;
639     }
640     else {
641         if (PL_lastscream) {
642             SvSCREAM_off(PL_lastscream);
643             SvREFCNT_dec(PL_lastscream);
644         }
645         PL_lastscream = SvREFCNT_inc(sv);
646     }
647
648     s = (unsigned char*)(SvPV(sv, len));
649     pos = len;
650     if (pos <= 0)
651         RETPUSHNO;
652     if (pos > PL_maxscream) {
653         if (PL_maxscream < 0) {
654             PL_maxscream = pos + 80;
655             Newx(PL_screamfirst, 256, I32);
656             Newx(PL_screamnext, PL_maxscream, I32);
657         }
658         else {
659             PL_maxscream = pos + pos / 4;
660             Renew(PL_screamnext, PL_maxscream, I32);
661         }
662     }
663
664     sfirst = PL_screamfirst;
665     snext = PL_screamnext;
666
667     if (!sfirst || !snext)
668         DIE(aTHX_ "do_study: out of memory");
669
670     for (ch = 256; ch; --ch)
671         *sfirst++ = -1;
672     sfirst -= 256;
673
674     while (--pos >= 0) {
675         register const I32 ch = s[pos];
676         if (sfirst[ch] >= 0)
677             snext[pos] = sfirst[ch] - pos;
678         else
679             snext[pos] = -pos;
680         sfirst[ch] = pos;
681     }
682
683     SvSCREAM_on(sv);
684     /* piggyback on m//g magic */
685     sv_magic(sv, NULL, PERL_MAGIC_regex_global, NULL, 0);
686     RETPUSHYES;
687 }
688
689 PP(pp_trans)
690 {
691     dVAR; dSP; dTARG;
692     SV *sv;
693
694     if (PL_op->op_flags & OPf_STACKED)
695         sv = POPs;
696     else if (PL_op->op_private & OPpTARGET_MY)
697         sv = GETTARGET;
698     else {
699         sv = DEFSV;
700         EXTEND(SP,1);
701     }
702     TARG = sv_newmortal();
703     PUSHi(do_trans(sv));
704     RETURN;
705 }
706
707 /* Lvalue operators. */
708
709 PP(pp_schop)
710 {
711     dVAR; dSP; dTARGET;
712     do_chop(TARG, TOPs);
713     SETTARG;
714     RETURN;
715 }
716
717 PP(pp_chop)
718 {
719     dVAR; dSP; dMARK; dTARGET; dORIGMARK;
720     while (MARK < SP)
721         do_chop(TARG, *++MARK);
722     SP = ORIGMARK;
723     XPUSHTARG;
724     RETURN;
725 }
726
727 PP(pp_schomp)
728 {
729     dVAR; dSP; dTARGET;
730     SETi(do_chomp(TOPs));
731     RETURN;
732 }
733
734 PP(pp_chomp)
735 {
736     dVAR; dSP; dMARK; dTARGET;
737     register I32 count = 0;
738
739     while (SP > MARK)
740         count += do_chomp(POPs);
741     XPUSHi(count);
742     RETURN;
743 }
744
745 PP(pp_undef)
746 {
747     dVAR; dSP;
748     SV *sv;
749
750     if (!PL_op->op_private) {
751         EXTEND(SP, 1);
752         RETPUSHUNDEF;
753     }
754
755     sv = POPs;
756     if (!sv)
757         RETPUSHUNDEF;
758
759     SV_CHECK_THINKFIRST_COW_DROP(sv);
760
761     switch (SvTYPE(sv)) {
762     case SVt_NULL:
763         break;
764     case SVt_PVAV:
765         av_undef((AV*)sv);
766         break;
767     case SVt_PVHV:
768         hv_undef((HV*)sv);
769         break;
770     case SVt_PVCV:
771         if (cv_const_sv((CV*)sv) && ckWARN(WARN_MISC))
772             Perl_warner(aTHX_ packWARN(WARN_MISC), "Constant subroutine %s undefined",
773                  CvANON((CV*)sv) ? "(anonymous)" : GvENAME(CvGV((CV*)sv)));
774         /* FALLTHROUGH */
775     case SVt_PVFM:
776         {
777             /* let user-undef'd sub keep its identity */
778             GV* const gv = CvGV((CV*)sv);
779             cv_undef((CV*)sv);
780             CvGV((CV*)sv) = gv;
781         }
782         break;
783     case SVt_PVGV:
784         if (SvFAKE(sv))
785             SvSetMagicSV(sv, &PL_sv_undef);
786         else {
787             GP *gp;
788             gp_free((GV*)sv);
789             Newxz(gp, 1, GP);
790             GvGP(sv) = gp_ref(gp);
791             GvSV(sv) = newSV(0);
792             GvLINE(sv) = CopLINE(PL_curcop);
793             GvEGV(sv) = (GV*)sv;
794             GvMULTI_on(sv);
795         }
796         break;
797     default:
798         if (SvTYPE(sv) >= SVt_PV && SvPVX_const(sv) && SvLEN(sv)) {
799             SvPV_free(sv);
800             SvPV_set(sv, NULL);
801             SvLEN_set(sv, 0);
802         }
803         SvOK_off(sv);
804         SvSETMAGIC(sv);
805     }
806
807     RETPUSHUNDEF;
808 }
809
810 PP(pp_predec)
811 {
812     dVAR; dSP;
813     if (SvTYPE(TOPs) >= SVt_PVGV && SvTYPE(TOPs) != SVt_PVLV)
814         DIE(aTHX_ PL_no_modify);
815     if (!SvREADONLY(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)
816         && SvIVX(TOPs) != IV_MIN)
817     {
818         SvIV_set(TOPs, SvIVX(TOPs) - 1);
819         SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
820     }
821     else
822         sv_dec(TOPs);
823     SvSETMAGIC(TOPs);
824     return NORMAL;
825 }
826
827 PP(pp_postinc)
828 {
829     dVAR; dSP; dTARGET;
830     if (SvTYPE(TOPs) >= SVt_PVGV && SvTYPE(TOPs) != SVt_PVLV)
831         DIE(aTHX_ PL_no_modify);
832     sv_setsv(TARG, TOPs);
833     if (!SvREADONLY(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)
834         && SvIVX(TOPs) != IV_MAX)
835     {
836         SvIV_set(TOPs, SvIVX(TOPs) + 1);
837         SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
838     }
839     else
840         sv_inc(TOPs);
841     SvSETMAGIC(TOPs);
842     /* special case for undef: see thread at 2003-03/msg00536.html in archive */
843     if (!SvOK(TARG))
844         sv_setiv(TARG, 0);
845     SETs(TARG);
846     return NORMAL;
847 }
848
849 PP(pp_postdec)
850 {
851     dVAR; dSP; dTARGET;
852     if (SvTYPE(TOPs) >= SVt_PVGV && SvTYPE(TOPs) != SVt_PVLV)
853         DIE(aTHX_ PL_no_modify);
854     sv_setsv(TARG, TOPs);
855     if (!SvREADONLY(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)
856         && SvIVX(TOPs) != IV_MIN)
857     {
858         SvIV_set(TOPs, SvIVX(TOPs) - 1);
859         SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
860     }
861     else
862         sv_dec(TOPs);
863     SvSETMAGIC(TOPs);
864     SETs(TARG);
865     return NORMAL;
866 }
867
868 /* Ordinary operators. */
869
870 PP(pp_pow)
871 {
872     dVAR; dSP; dATARGET;
873 #ifdef PERL_PRESERVE_IVUV
874     bool is_int = 0;
875 #endif
876     tryAMAGICbin(pow,opASSIGN);
877 #ifdef PERL_PRESERVE_IVUV
878     /* For integer to integer power, we do the calculation by hand wherever
879        we're sure it is safe; otherwise we call pow() and try to convert to
880        integer afterwards. */
881     {
882         SvIV_please(TOPs);
883         if (SvIOK(TOPs)) {
884             SvIV_please(TOPm1s);
885             if (SvIOK(TOPm1s)) {
886                 UV power;
887                 bool baseuok;
888                 UV baseuv;
889
890                 if (SvUOK(TOPs)) {
891                     power = SvUVX(TOPs);
892                 } else {
893                     const IV iv = SvIVX(TOPs);
894                     if (iv >= 0) {
895                         power = iv;
896                     } else {
897                         goto float_it; /* Can't do negative powers this way.  */
898                     }
899                 }
900
901                 baseuok = SvUOK(TOPm1s);
902                 if (baseuok) {
903                     baseuv = SvUVX(TOPm1s);
904                 } else {
905                     const IV iv = SvIVX(TOPm1s);
906                     if (iv >= 0) {
907                         baseuv = iv;
908                         baseuok = TRUE; /* effectively it's a UV now */
909                     } else {
910                         baseuv = -iv; /* abs, baseuok == false records sign */
911                     }
912                 }
913                 /* now we have integer ** positive integer. */
914                 is_int = 1;
915
916                 /* foo & (foo - 1) is zero only for a power of 2.  */
917                 if (!(baseuv & (baseuv - 1))) {
918                     /* We are raising power-of-2 to a positive integer.
919                        The logic here will work for any base (even non-integer
920                        bases) but it can be less accurate than
921                        pow (base,power) or exp (power * log (base)) when the
922                        intermediate values start to spill out of the mantissa.
923                        With powers of 2 we know this can't happen.
924                        And powers of 2 are the favourite thing for perl
925                        programmers to notice ** not doing what they mean. */
926                     NV result = 1.0;
927                     NV base = baseuok ? baseuv : -(NV)baseuv;
928
929                     if (power & 1) {
930                         result *= base;
931                     }
932                     while (power >>= 1) {
933                         base *= base;
934                         if (power & 1) {
935                             result *= base;
936                         }
937                     }
938                     SP--;
939                     SETn( result );
940                     SvIV_please(TOPs);
941                     RETURN;
942                 } else {
943                     register unsigned int highbit = 8 * sizeof(UV);
944                     register unsigned int diff = 8 * sizeof(UV);
945                     while (diff >>= 1) {
946                         highbit -= diff;
947                         if (baseuv >> highbit) {
948                             highbit += diff;
949                         }
950                     }
951                     /* we now have baseuv < 2 ** highbit */
952                     if (power * highbit <= 8 * sizeof(UV)) {
953                         /* result will definitely fit in UV, so use UV math
954                            on same algorithm as above */
955                         register UV result = 1;
956                         register UV base = baseuv;
957                         const bool odd_power = (bool)(power & 1);
958                         if (odd_power) {
959                             result *= base;
960                         }
961                         while (power >>= 1) {
962                             base *= base;
963                             if (power & 1) {
964                                 result *= base;
965                             }
966                         }
967                         SP--;
968                         if (baseuok || !odd_power)
969                             /* answer is positive */
970                             SETu( result );
971                         else if (result <= (UV)IV_MAX)
972                             /* answer negative, fits in IV */
973                             SETi( -(IV)result );
974                         else if (result == (UV)IV_MIN) 
975                             /* 2's complement assumption: special case IV_MIN */
976                             SETi( IV_MIN );
977                         else
978                             /* answer negative, doesn't fit */
979                             SETn( -(NV)result );
980                         RETURN;
981                     } 
982                 }
983             }
984         }
985     }
986   float_it:
987 #endif    
988     {
989         dPOPTOPnnrl;
990         SETn( Perl_pow( left, right) );
991 #ifdef PERL_PRESERVE_IVUV
992         if (is_int)
993             SvIV_please(TOPs);
994 #endif
995         RETURN;
996     }
997 }
998
999 PP(pp_multiply)
1000 {
1001     dVAR; dSP; dATARGET; tryAMAGICbin(mult,opASSIGN);
1002 #ifdef PERL_PRESERVE_IVUV
1003     SvIV_please(TOPs);
1004     if (SvIOK(TOPs)) {
1005         /* Unless the left argument is integer in range we are going to have to
1006            use NV maths. Hence only attempt to coerce the right argument if
1007            we know the left is integer.  */
1008         /* Left operand is defined, so is it IV? */
1009         SvIV_please(TOPm1s);
1010         if (SvIOK(TOPm1s)) {
1011             bool auvok = SvUOK(TOPm1s);
1012             bool buvok = SvUOK(TOPs);
1013             const UV topmask = (~ (UV)0) << (4 * sizeof (UV));
1014             const UV botmask = ~((~ (UV)0) << (4 * sizeof (UV)));
1015             UV alow;
1016             UV ahigh;
1017             UV blow;
1018             UV bhigh;
1019
1020             if (auvok) {
1021                 alow = SvUVX(TOPm1s);
1022             } else {
1023                 const IV aiv = SvIVX(TOPm1s);
1024                 if (aiv >= 0) {
1025                     alow = aiv;
1026                     auvok = TRUE; /* effectively it's a UV now */
1027                 } else {
1028                     alow = -aiv; /* abs, auvok == false records sign */
1029                 }
1030             }
1031             if (buvok) {
1032                 blow = SvUVX(TOPs);
1033             } else {
1034                 const IV biv = SvIVX(TOPs);
1035                 if (biv >= 0) {
1036                     blow = biv;
1037                     buvok = TRUE; /* effectively it's a UV now */
1038                 } else {
1039                     blow = -biv; /* abs, buvok == false records sign */
1040                 }
1041             }
1042
1043             /* If this does sign extension on unsigned it's time for plan B  */
1044             ahigh = alow >> (4 * sizeof (UV));
1045             alow &= botmask;
1046             bhigh = blow >> (4 * sizeof (UV));
1047             blow &= botmask;
1048             if (ahigh && bhigh) {
1049                 /* eg 32 bit is at least 0x10000 * 0x10000 == 0x100000000
1050                    which is overflow. Drop to NVs below.  */
1051             } else if (!ahigh && !bhigh) {
1052                 /* eg 32 bit is at most 0xFFFF * 0xFFFF == 0xFFFE0001
1053                    so the unsigned multiply cannot overflow.  */
1054                 const UV product = alow * blow;
1055                 if (auvok == buvok) {
1056                     /* -ve * -ve or +ve * +ve gives a +ve result.  */
1057                     SP--;
1058                     SETu( product );
1059                     RETURN;
1060                 } else if (product <= (UV)IV_MIN) {
1061                     /* 2s complement assumption that (UV)-IV_MIN is correct.  */
1062                     /* -ve result, which could overflow an IV  */
1063                     SP--;
1064                     SETi( -(IV)product );
1065                     RETURN;
1066                 } /* else drop to NVs below. */
1067             } else {
1068                 /* One operand is large, 1 small */
1069                 UV product_middle;
1070                 if (bhigh) {
1071                     /* swap the operands */
1072                     ahigh = bhigh;
1073                     bhigh = blow; /* bhigh now the temp var for the swap */
1074                     blow = alow;
1075                     alow = bhigh;
1076                 }
1077                 /* now, ((ahigh * blow) << half_UV_len) + (alow * blow)
1078                    multiplies can't overflow. shift can, add can, -ve can.  */
1079                 product_middle = ahigh * blow;
1080                 if (!(product_middle & topmask)) {
1081                     /* OK, (ahigh * blow) won't lose bits when we shift it.  */
1082                     UV product_low;
1083                     product_middle <<= (4 * sizeof (UV));
1084                     product_low = alow * blow;
1085
1086                     /* as for pp_add, UV + something mustn't get smaller.
1087                        IIRC ANSI mandates this wrapping *behaviour* for
1088                        unsigned whatever the actual representation*/
1089                     product_low += product_middle;
1090                     if (product_low >= product_middle) {
1091                         /* didn't overflow */
1092                         if (auvok == buvok) {
1093                             /* -ve * -ve or +ve * +ve gives a +ve result.  */
1094                             SP--;
1095                             SETu( product_low );
1096                             RETURN;
1097                         } else if (product_low <= (UV)IV_MIN) {
1098                             /* 2s complement assumption again  */
1099                             /* -ve result, which could overflow an IV  */
1100                             SP--;
1101                             SETi( -(IV)product_low );
1102                             RETURN;
1103                         } /* else drop to NVs below. */
1104                     }
1105                 } /* product_middle too large */
1106             } /* ahigh && bhigh */
1107         } /* SvIOK(TOPm1s) */
1108     } /* SvIOK(TOPs) */
1109 #endif
1110     {
1111       dPOPTOPnnrl;
1112       SETn( left * right );
1113       RETURN;
1114     }
1115 }
1116
1117 PP(pp_divide)
1118 {
1119     dVAR; dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
1120     /* Only try to do UV divide first
1121        if ((SLOPPYDIVIDE is true) or
1122            (PERL_PRESERVE_IVUV is true and one or both SV is a UV too large
1123             to preserve))
1124        The assumption is that it is better to use floating point divide
1125        whenever possible, only doing integer divide first if we can't be sure.
1126        If NV_PRESERVES_UV is true then we know at compile time that no UV
1127        can be too large to preserve, so don't need to compile the code to
1128        test the size of UVs.  */
1129
1130 #ifdef SLOPPYDIVIDE
1131 #  define PERL_TRY_UV_DIVIDE
1132     /* ensure that 20./5. == 4. */
1133 #else
1134 #  ifdef PERL_PRESERVE_IVUV
1135 #    ifndef NV_PRESERVES_UV
1136 #      define PERL_TRY_UV_DIVIDE
1137 #    endif
1138 #  endif
1139 #endif
1140
1141 #ifdef PERL_TRY_UV_DIVIDE
1142     SvIV_please(TOPs);
1143     if (SvIOK(TOPs)) {
1144         SvIV_please(TOPm1s);
1145         if (SvIOK(TOPm1s)) {
1146             bool left_non_neg = SvUOK(TOPm1s);
1147             bool right_non_neg = SvUOK(TOPs);
1148             UV left;
1149             UV right;
1150
1151             if (right_non_neg) {
1152                 right = SvUVX(TOPs);
1153             }
1154             else {
1155                 const IV biv = SvIVX(TOPs);
1156                 if (biv >= 0) {
1157                     right = biv;
1158                     right_non_neg = TRUE; /* effectively it's a UV now */
1159                 }
1160                 else {
1161                     right = -biv;
1162                 }
1163             }
1164             /* historically undef()/0 gives a "Use of uninitialized value"
1165                warning before dieing, hence this test goes here.
1166                If it were immediately before the second SvIV_please, then
1167                DIE() would be invoked before left was even inspected, so
1168                no inpsection would give no warning.  */
1169             if (right == 0)
1170                 DIE(aTHX_ "Illegal division by zero");
1171
1172             if (left_non_neg) {
1173                 left = SvUVX(TOPm1s);
1174             }
1175             else {
1176                 const IV aiv = SvIVX(TOPm1s);
1177                 if (aiv >= 0) {
1178                     left = aiv;
1179                     left_non_neg = TRUE; /* effectively it's a UV now */
1180                 }
1181                 else {
1182                     left = -aiv;
1183                 }
1184             }
1185
1186             if (left >= right
1187 #ifdef SLOPPYDIVIDE
1188                 /* For sloppy divide we always attempt integer division.  */
1189 #else
1190                 /* Otherwise we only attempt it if either or both operands
1191                    would not be preserved by an NV.  If both fit in NVs
1192                    we fall through to the NV divide code below.  However,
1193                    as left >= right to ensure integer result here, we know that
1194                    we can skip the test on the right operand - right big
1195                    enough not to be preserved can't get here unless left is
1196                    also too big.  */
1197
1198                 && (left > ((UV)1 << NV_PRESERVES_UV_BITS))
1199 #endif
1200                 ) {
1201                 /* Integer division can't overflow, but it can be imprecise.  */
1202                 const UV result = left / right;
1203                 if (result * right == left) {
1204                     SP--; /* result is valid */
1205                     if (left_non_neg == right_non_neg) {
1206                         /* signs identical, result is positive.  */
1207                         SETu( result );
1208                         RETURN;
1209                     }
1210                     /* 2s complement assumption */
1211                     if (result <= (UV)IV_MIN)
1212                         SETi( -(IV)result );
1213                     else {
1214                         /* It's exact but too negative for IV. */
1215                         SETn( -(NV)result );
1216                     }
1217                     RETURN;
1218                 } /* tried integer divide but it was not an integer result */
1219             } /* else (PERL_ABS(result) < 1.0) or (both UVs in range for NV) */
1220         } /* left wasn't SvIOK */
1221     } /* right wasn't SvIOK */
1222 #endif /* PERL_TRY_UV_DIVIDE */
1223     {
1224         dPOPPOPnnrl;
1225         if (right == 0.0)
1226             DIE(aTHX_ "Illegal division by zero");
1227         PUSHn( left / right );
1228         RETURN;
1229     }
1230 }
1231
1232 PP(pp_modulo)
1233 {
1234     dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
1235     {
1236         UV left  = 0;
1237         UV right = 0;
1238         bool left_neg = FALSE;
1239         bool right_neg = FALSE;
1240         bool use_double = FALSE;
1241         bool dright_valid = FALSE;
1242         NV dright = 0.0;
1243         NV dleft  = 0.0;
1244
1245         SvIV_please(TOPs);
1246         if (SvIOK(TOPs)) {
1247             right_neg = !SvUOK(TOPs);
1248             if (!right_neg) {
1249                 right = SvUVX(POPs);
1250             } else {
1251                 const IV biv = SvIVX(POPs);
1252                 if (biv >= 0) {
1253                     right = biv;
1254                     right_neg = FALSE; /* effectively it's a UV now */
1255                 } else {
1256                     right = -biv;
1257                 }
1258             }
1259         }
1260         else {
1261             dright = POPn;
1262             right_neg = dright < 0;
1263             if (right_neg)
1264                 dright = -dright;
1265             if (dright < UV_MAX_P1) {
1266                 right = U_V(dright);
1267                 dright_valid = TRUE; /* In case we need to use double below.  */
1268             } else {
1269                 use_double = TRUE;
1270             }
1271         }
1272
1273         /* At this point use_double is only true if right is out of range for
1274            a UV.  In range NV has been rounded down to nearest UV and
1275            use_double false.  */
1276         SvIV_please(TOPs);
1277         if (!use_double && SvIOK(TOPs)) {
1278             if (SvIOK(TOPs)) {
1279                 left_neg = !SvUOK(TOPs);
1280                 if (!left_neg) {
1281                     left = SvUVX(POPs);
1282                 } else {
1283                     const IV aiv = SvIVX(POPs);
1284                     if (aiv >= 0) {
1285                         left = aiv;
1286                         left_neg = FALSE; /* effectively it's a UV now */
1287                     } else {
1288                         left = -aiv;
1289                     }
1290                 }
1291             }
1292         }
1293         else {
1294             dleft = POPn;
1295             left_neg = dleft < 0;
1296             if (left_neg)
1297                 dleft = -dleft;
1298
1299             /* This should be exactly the 5.6 behaviour - if left and right are
1300                both in range for UV then use U_V() rather than floor.  */
1301             if (!use_double) {
1302                 if (dleft < UV_MAX_P1) {
1303                     /* right was in range, so is dleft, so use UVs not double.
1304                      */
1305                     left = U_V(dleft);
1306                 }
1307                 /* left is out of range for UV, right was in range, so promote
1308                    right (back) to double.  */
1309                 else {
1310                     /* The +0.5 is used in 5.6 even though it is not strictly
1311                        consistent with the implicit +0 floor in the U_V()
1312                        inside the #if 1. */
1313                     dleft = Perl_floor(dleft + 0.5);
1314                     use_double = TRUE;
1315                     if (dright_valid)
1316                         dright = Perl_floor(dright + 0.5);
1317                     else
1318                         dright = right;
1319                 }
1320             }
1321         }
1322         if (use_double) {
1323             NV dans;
1324
1325             if (!dright)
1326                 DIE(aTHX_ "Illegal modulus zero");
1327
1328             dans = Perl_fmod(dleft, dright);
1329             if ((left_neg != right_neg) && dans)
1330                 dans = dright - dans;
1331             if (right_neg)
1332                 dans = -dans;
1333             sv_setnv(TARG, dans);
1334         }
1335         else {
1336             UV ans;
1337
1338             if (!right)
1339                 DIE(aTHX_ "Illegal modulus zero");
1340
1341             ans = left % right;
1342             if ((left_neg != right_neg) && ans)
1343                 ans = right - ans;
1344             if (right_neg) {
1345                 /* XXX may warn: unary minus operator applied to unsigned type */
1346                 /* could change -foo to be (~foo)+1 instead     */
1347                 if (ans <= ~((UV)IV_MAX)+1)
1348                     sv_setiv(TARG, ~ans+1);
1349                 else
1350                     sv_setnv(TARG, -(NV)ans);
1351             }
1352             else
1353                 sv_setuv(TARG, ans);
1354         }
1355         PUSHTARG;
1356         RETURN;
1357     }
1358 }
1359
1360 PP(pp_repeat)
1361 {
1362   dVAR; dSP; dATARGET; tryAMAGICbin(repeat,opASSIGN);
1363   {
1364     register IV count;
1365     dPOPss;
1366     SvGETMAGIC(sv);
1367     if (SvIOKp(sv)) {
1368          if (SvUOK(sv)) {
1369               const UV uv = SvUV(sv);
1370               if (uv > IV_MAX)
1371                    count = IV_MAX; /* The best we can do? */
1372               else
1373                    count = uv;
1374          } else {
1375               const IV iv = SvIV(sv);
1376               if (iv < 0)
1377                    count = 0;
1378               else
1379                    count = iv;
1380          }
1381     }
1382     else if (SvNOKp(sv)) {
1383          const NV nv = SvNV(sv);
1384          if (nv < 0.0)
1385               count = 0;
1386          else
1387               count = (IV)nv;
1388     }
1389     else
1390          count = SvIVx(sv);
1391     if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) {
1392         dMARK;
1393         static const char oom_list_extend[] = "Out of memory during list extend";
1394         const I32 items = SP - MARK;
1395         const I32 max = items * count;
1396
1397         MEM_WRAP_CHECK_1(max, SV*, oom_list_extend);
1398         /* Did the max computation overflow? */
1399         if (items > 0 && max > 0 && (max < items || max < count))
1400            Perl_croak(aTHX_ oom_list_extend);
1401         MEXTEND(MARK, max);
1402         if (count > 1) {
1403             while (SP > MARK) {
1404 #if 0
1405               /* This code was intended to fix 20010809.028:
1406
1407                  $x = 'abcd';
1408                  for (($x =~ /./g) x 2) {
1409                      print chop; # "abcdabcd" expected as output.
1410                  }
1411
1412                * but that change (#11635) broke this code:
1413
1414                $x = [("foo")x2]; # only one "foo" ended up in the anonlist.
1415
1416                * I can't think of a better fix that doesn't introduce
1417                * an efficiency hit by copying the SVs. The stack isn't
1418                * refcounted, and mortalisation obviously doesn't
1419                * Do The Right Thing when the stack has more than
1420                * one pointer to the same mortal value.
1421                * .robin.
1422                */
1423                 if (*SP) {
1424                     *SP = sv_2mortal(newSVsv(*SP));
1425                     SvREADONLY_on(*SP);
1426                 }
1427 #else
1428                if (*SP)
1429                    SvTEMP_off((*SP));
1430 #endif
1431                 SP--;
1432             }
1433             MARK++;
1434             repeatcpy((char*)(MARK + items), (char*)MARK,
1435                 items * sizeof(SV*), count - 1);
1436             SP += max;
1437         }
1438         else if (count <= 0)
1439             SP -= items;
1440     }
1441     else {      /* Note: mark already snarfed by pp_list */
1442         SV * const tmpstr = POPs;
1443         STRLEN len;
1444         bool isutf;
1445         static const char oom_string_extend[] =
1446           "Out of memory during string extend";
1447
1448         SvSetSV(TARG, tmpstr);
1449         SvPV_force(TARG, len);
1450         isutf = DO_UTF8(TARG);
1451         if (count != 1) {
1452             if (count < 1)
1453                 SvCUR_set(TARG, 0);
1454             else {
1455                 const STRLEN max = (UV)count * len;
1456                 if (len > ((MEM_SIZE)~0)/count)
1457                      Perl_croak(aTHX_ oom_string_extend);
1458                 MEM_WRAP_CHECK_1(max, char, oom_string_extend);
1459                 SvGROW(TARG, max + 1);
1460                 repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
1461                 SvCUR_set(TARG, SvCUR(TARG) * count);
1462             }
1463             *SvEND(TARG) = '\0';
1464         }
1465         if (isutf)
1466             (void)SvPOK_only_UTF8(TARG);
1467         else
1468             (void)SvPOK_only(TARG);
1469
1470         if (PL_op->op_private & OPpREPEAT_DOLIST) {
1471             /* The parser saw this as a list repeat, and there
1472                are probably several items on the stack. But we're
1473                in scalar context, and there's no pp_list to save us
1474                now. So drop the rest of the items -- robin@kitsite.com
1475              */
1476             dMARK;
1477             SP = MARK;
1478         }
1479         PUSHTARG;
1480     }
1481     RETURN;
1482   }
1483 }
1484
1485 PP(pp_subtract)
1486 {
1487     dVAR; dSP; dATARGET; bool useleft; tryAMAGICbin(subtr,opASSIGN);
1488     useleft = USE_LEFT(TOPm1s);
1489 #ifdef PERL_PRESERVE_IVUV
1490     /* See comments in pp_add (in pp_hot.c) about Overflow, and how
1491        "bad things" happen if you rely on signed integers wrapping.  */
1492     SvIV_please(TOPs);
1493     if (SvIOK(TOPs)) {
1494         /* Unless the left argument is integer in range we are going to have to
1495            use NV maths. Hence only attempt to coerce the right argument if
1496            we know the left is integer.  */
1497         register UV auv = 0;
1498         bool auvok = FALSE;
1499         bool a_valid = 0;
1500
1501         if (!useleft) {
1502             auv = 0;
1503             a_valid = auvok = 1;
1504             /* left operand is undef, treat as zero.  */
1505         } else {
1506             /* Left operand is defined, so is it IV? */
1507             SvIV_please(TOPm1s);
1508             if (SvIOK(TOPm1s)) {
1509                 if ((auvok = SvUOK(TOPm1s)))
1510                     auv = SvUVX(TOPm1s);
1511                 else {
1512                     register const IV aiv = SvIVX(TOPm1s);
1513                     if (aiv >= 0) {
1514                         auv = aiv;
1515                         auvok = 1;      /* Now acting as a sign flag.  */
1516                     } else { /* 2s complement assumption for IV_MIN */
1517                         auv = (UV)-aiv;
1518                     }
1519                 }
1520                 a_valid = 1;
1521             }
1522         }
1523         if (a_valid) {
1524             bool result_good = 0;
1525             UV result;
1526             register UV buv;
1527             bool buvok = SvUOK(TOPs);
1528         
1529             if (buvok)
1530                 buv = SvUVX(TOPs);
1531             else {
1532                 register const IV biv = SvIVX(TOPs);
1533                 if (biv >= 0) {
1534                     buv = biv;
1535                     buvok = 1;
1536                 } else
1537                     buv = (UV)-biv;
1538             }
1539             /* ?uvok if value is >= 0. basically, flagged as UV if it's +ve,
1540                else "IV" now, independent of how it came in.
1541                if a, b represents positive, A, B negative, a maps to -A etc
1542                a - b =>  (a - b)
1543                A - b => -(a + b)
1544                a - B =>  (a + b)
1545                A - B => -(a - b)
1546                all UV maths. negate result if A negative.
1547                subtract if signs same, add if signs differ. */
1548
1549             if (auvok ^ buvok) {
1550                 /* Signs differ.  */
1551                 result = auv + buv;
1552                 if (result >= auv)
1553                     result_good = 1;
1554             } else {
1555                 /* Signs same */
1556                 if (auv >= buv) {
1557                     result = auv - buv;
1558                     /* Must get smaller */
1559                     if (result <= auv)
1560                         result_good = 1;
1561                 } else {
1562                     result = buv - auv;
1563                     if (result <= buv) {
1564                         /* result really should be -(auv-buv). as its negation
1565                            of true value, need to swap our result flag  */
1566                         auvok = !auvok;
1567                         result_good = 1;
1568                     }
1569                 }
1570             }
1571             if (result_good) {
1572                 SP--;
1573                 if (auvok)
1574                     SETu( result );
1575                 else {
1576                     /* Negate result */
1577                     if (result <= (UV)IV_MIN)
1578                         SETi( -(IV)result );
1579                     else {
1580                         /* result valid, but out of range for IV.  */
1581                         SETn( -(NV)result );
1582                     }
1583                 }
1584                 RETURN;
1585             } /* Overflow, drop through to NVs.  */
1586         }
1587     }
1588 #endif
1589     useleft = USE_LEFT(TOPm1s);
1590     {
1591         dPOPnv;
1592         if (!useleft) {
1593             /* left operand is undef, treat as zero - value */
1594             SETn(-value);
1595             RETURN;
1596         }
1597         SETn( TOPn - value );
1598         RETURN;
1599     }
1600 }
1601
1602 PP(pp_left_shift)
1603 {
1604     dVAR; dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN);
1605     {
1606       const IV shift = POPi;
1607       if (PL_op->op_private & HINT_INTEGER) {
1608         const IV i = TOPi;
1609         SETi(i << shift);
1610       }
1611       else {
1612         const UV u = TOPu;
1613         SETu(u << shift);
1614       }
1615       RETURN;
1616     }
1617 }
1618
1619 PP(pp_right_shift)
1620 {
1621     dVAR; dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN);
1622     {
1623       const IV shift = POPi;
1624       if (PL_op->op_private & HINT_INTEGER) {
1625         const IV i = TOPi;
1626         SETi(i >> shift);
1627       }
1628       else {
1629         const UV u = TOPu;
1630         SETu(u >> shift);
1631       }
1632       RETURN;
1633     }
1634 }
1635
1636 PP(pp_lt)
1637 {
1638     dVAR; dSP; tryAMAGICbinSET(lt,0);
1639 #ifdef PERL_PRESERVE_IVUV
1640     SvIV_please(TOPs);
1641     if (SvIOK(TOPs)) {
1642         SvIV_please(TOPm1s);
1643         if (SvIOK(TOPm1s)) {
1644             bool auvok = SvUOK(TOPm1s);
1645             bool buvok = SvUOK(TOPs);
1646         
1647             if (!auvok && !buvok) { /* ## IV < IV ## */
1648                 const IV aiv = SvIVX(TOPm1s);
1649                 const IV biv = SvIVX(TOPs);
1650                 
1651                 SP--;
1652                 SETs(boolSV(aiv < biv));
1653                 RETURN;
1654             }
1655             if (auvok && buvok) { /* ## UV < UV ## */
1656                 const UV auv = SvUVX(TOPm1s);
1657                 const UV buv = SvUVX(TOPs);
1658                 
1659                 SP--;
1660                 SETs(boolSV(auv < buv));
1661                 RETURN;
1662             }
1663             if (auvok) { /* ## UV < IV ## */
1664                 UV auv;
1665                 const IV biv = SvIVX(TOPs);
1666                 SP--;
1667                 if (biv < 0) {
1668                     /* As (a) is a UV, it's >=0, so it cannot be < */
1669                     SETs(&PL_sv_no);
1670                     RETURN;
1671                 }
1672                 auv = SvUVX(TOPs);
1673                 SETs(boolSV(auv < (UV)biv));
1674                 RETURN;
1675             }
1676             { /* ## IV < UV ## */
1677                 const IV aiv = SvIVX(TOPm1s);
1678                 UV buv;
1679                 
1680                 if (aiv < 0) {
1681                     /* As (b) is a UV, it's >=0, so it must be < */
1682                     SP--;
1683                     SETs(&PL_sv_yes);
1684                     RETURN;
1685                 }
1686                 buv = SvUVX(TOPs);
1687                 SP--;
1688                 SETs(boolSV((UV)aiv < buv));
1689                 RETURN;
1690             }
1691         }
1692     }
1693 #endif
1694 #ifndef NV_PRESERVES_UV
1695 #ifdef PERL_PRESERVE_IVUV
1696     else
1697 #endif
1698     if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) {
1699         SP--;
1700         SETs(boolSV(SvRV(TOPs) < SvRV(TOPp1s)));
1701         RETURN;
1702     }
1703 #endif
1704     {
1705       dPOPnv;
1706       SETs(boolSV(TOPn < value));
1707       RETURN;
1708     }
1709 }
1710
1711 PP(pp_gt)
1712 {
1713     dVAR; dSP; tryAMAGICbinSET(gt,0);
1714 #ifdef PERL_PRESERVE_IVUV
1715     SvIV_please(TOPs);
1716     if (SvIOK(TOPs)) {
1717         SvIV_please(TOPm1s);
1718         if (SvIOK(TOPm1s)) {
1719             bool auvok = SvUOK(TOPm1s);
1720             bool buvok = SvUOK(TOPs);
1721         
1722             if (!auvok && !buvok) { /* ## IV > IV ## */
1723                 const IV aiv = SvIVX(TOPm1s);
1724                 const IV biv = SvIVX(TOPs);
1725
1726                 SP--;
1727                 SETs(boolSV(aiv > biv));
1728                 RETURN;
1729             }
1730             if (auvok && buvok) { /* ## UV > UV ## */
1731                 const UV auv = SvUVX(TOPm1s);
1732                 const UV buv = SvUVX(TOPs);
1733                 
1734                 SP--;
1735                 SETs(boolSV(auv > buv));
1736                 RETURN;
1737             }
1738             if (auvok) { /* ## UV > IV ## */
1739                 UV auv;
1740                 const IV biv = SvIVX(TOPs);
1741
1742                 SP--;
1743                 if (biv < 0) {
1744                     /* As (a) is a UV, it's >=0, so it must be > */
1745                     SETs(&PL_sv_yes);
1746                     RETURN;
1747                 }
1748                 auv = SvUVX(TOPs);
1749                 SETs(boolSV(auv > (UV)biv));
1750                 RETURN;
1751             }
1752             { /* ## IV > UV ## */
1753                 const IV aiv = SvIVX(TOPm1s);
1754                 UV buv;
1755                 
1756                 if (aiv < 0) {
1757                     /* As (b) is a UV, it's >=0, so it cannot be > */
1758                     SP--;
1759                     SETs(&PL_sv_no);
1760                     RETURN;
1761                 }
1762                 buv = SvUVX(TOPs);
1763                 SP--;
1764                 SETs(boolSV((UV)aiv > buv));
1765                 RETURN;
1766             }
1767         }
1768     }
1769 #endif
1770 #ifndef NV_PRESERVES_UV
1771 #ifdef PERL_PRESERVE_IVUV
1772     else
1773 #endif
1774     if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) {
1775         SP--;
1776         SETs(boolSV(SvRV(TOPs) > SvRV(TOPp1s)));
1777         RETURN;
1778     }
1779 #endif
1780     {
1781       dPOPnv;
1782       SETs(boolSV(TOPn > value));
1783       RETURN;
1784     }
1785 }
1786
1787 PP(pp_le)
1788 {
1789     dVAR; dSP; tryAMAGICbinSET(le,0);
1790 #ifdef PERL_PRESERVE_IVUV
1791     SvIV_please(TOPs);
1792     if (SvIOK(TOPs)) {
1793         SvIV_please(TOPm1s);
1794         if (SvIOK(TOPm1s)) {
1795             bool auvok = SvUOK(TOPm1s);
1796             bool buvok = SvUOK(TOPs);
1797         
1798             if (!auvok && !buvok) { /* ## IV <= IV ## */
1799                 const IV aiv = SvIVX(TOPm1s);
1800                 const IV biv = SvIVX(TOPs);
1801                 
1802                 SP--;
1803                 SETs(boolSV(aiv <= biv));
1804                 RETURN;
1805             }
1806             if (auvok && buvok) { /* ## UV <= UV ## */
1807                 UV auv = SvUVX(TOPm1s);
1808                 UV buv = SvUVX(TOPs);
1809                 
1810                 SP--;
1811                 SETs(boolSV(auv <= buv));
1812                 RETURN;
1813             }
1814             if (auvok) { /* ## UV <= IV ## */
1815                 UV auv;
1816                 const IV biv = SvIVX(TOPs);
1817
1818                 SP--;
1819                 if (biv < 0) {
1820                     /* As (a) is a UV, it's >=0, so a cannot be <= */
1821                     SETs(&PL_sv_no);
1822                     RETURN;
1823                 }
1824                 auv = SvUVX(TOPs);
1825                 SETs(boolSV(auv <= (UV)biv));
1826                 RETURN;
1827             }
1828             { /* ## IV <= UV ## */
1829                 const IV aiv = SvIVX(TOPm1s);
1830                 UV buv;
1831
1832                 if (aiv < 0) {
1833                     /* As (b) is a UV, it's >=0, so a must be <= */
1834                     SP--;
1835                     SETs(&PL_sv_yes);
1836                     RETURN;
1837                 }
1838                 buv = SvUVX(TOPs);
1839                 SP--;
1840                 SETs(boolSV((UV)aiv <= buv));
1841                 RETURN;
1842             }
1843         }
1844     }
1845 #endif
1846 #ifndef NV_PRESERVES_UV
1847 #ifdef PERL_PRESERVE_IVUV
1848     else
1849 #endif
1850     if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) {
1851         SP--;
1852         SETs(boolSV(SvRV(TOPs) <= SvRV(TOPp1s)));
1853         RETURN;
1854     }
1855 #endif
1856     {
1857       dPOPnv;
1858       SETs(boolSV(TOPn <= value));
1859       RETURN;
1860     }
1861 }
1862
1863 PP(pp_ge)
1864 {
1865     dVAR; dSP; tryAMAGICbinSET(ge,0);
1866 #ifdef PERL_PRESERVE_IVUV
1867     SvIV_please(TOPs);
1868     if (SvIOK(TOPs)) {
1869         SvIV_please(TOPm1s);
1870         if (SvIOK(TOPm1s)) {
1871             bool auvok = SvUOK(TOPm1s);
1872             bool buvok = SvUOK(TOPs);
1873         
1874             if (!auvok && !buvok) { /* ## IV >= IV ## */
1875                 const IV aiv = SvIVX(TOPm1s);
1876                 const IV biv = SvIVX(TOPs);
1877
1878                 SP--;
1879                 SETs(boolSV(aiv >= biv));
1880                 RETURN;
1881             }
1882             if (auvok && buvok) { /* ## UV >= UV ## */
1883                 const UV auv = SvUVX(TOPm1s);
1884                 const UV buv = SvUVX(TOPs);
1885
1886                 SP--;
1887                 SETs(boolSV(auv >= buv));
1888                 RETURN;
1889             }
1890             if (auvok) { /* ## UV >= IV ## */
1891                 UV auv;
1892                 const IV biv = SvIVX(TOPs);
1893
1894                 SP--;
1895                 if (biv < 0) {
1896                     /* As (a) is a UV, it's >=0, so it must be >= */
1897                     SETs(&PL_sv_yes);
1898                     RETURN;
1899                 }
1900                 auv = SvUVX(TOPs);
1901                 SETs(boolSV(auv >= (UV)biv));
1902                 RETURN;
1903             }
1904             { /* ## IV >= UV ## */
1905                 const IV aiv = SvIVX(TOPm1s);
1906                 UV buv;
1907
1908                 if (aiv < 0) {
1909                     /* As (b) is a UV, it's >=0, so a cannot be >= */
1910                     SP--;
1911                     SETs(&PL_sv_no);
1912                     RETURN;
1913                 }
1914                 buv = SvUVX(TOPs);
1915                 SP--;
1916                 SETs(boolSV((UV)aiv >= buv));
1917                 RETURN;
1918             }
1919         }
1920     }
1921 #endif
1922 #ifndef NV_PRESERVES_UV
1923 #ifdef PERL_PRESERVE_IVUV
1924     else
1925 #endif
1926     if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) {
1927         SP--;
1928         SETs(boolSV(SvRV(TOPs) >= SvRV(TOPp1s)));
1929         RETURN;
1930     }
1931 #endif
1932     {
1933       dPOPnv;
1934       SETs(boolSV(TOPn >= value));
1935       RETURN;
1936     }
1937 }
1938
1939 PP(pp_ne)
1940 {
1941     dVAR; dSP; tryAMAGICbinSET(ne,0);
1942 #ifndef NV_PRESERVES_UV
1943     if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) {
1944         SP--;
1945         SETs(boolSV(SvRV(TOPs) != SvRV(TOPp1s)));
1946         RETURN;
1947     }
1948 #endif
1949 #ifdef PERL_PRESERVE_IVUV
1950     SvIV_please(TOPs);
1951     if (SvIOK(TOPs)) {
1952         SvIV_please(TOPm1s);
1953         if (SvIOK(TOPm1s)) {
1954             const bool auvok = SvUOK(TOPm1s);
1955             const bool buvok = SvUOK(TOPs);
1956         
1957             if (auvok == buvok) { /* ## IV == IV or UV == UV ## */
1958                 /* Casting IV to UV before comparison isn't going to matter
1959                    on 2s complement. On 1s complement or sign&magnitude
1960                    (if we have any of them) it could make negative zero
1961                    differ from normal zero. As I understand it. (Need to
1962                    check - is negative zero implementation defined behaviour
1963                    anyway?). NWC  */
1964                 const UV buv = SvUVX(POPs);
1965                 const UV auv = SvUVX(TOPs);
1966
1967                 SETs(boolSV(auv != buv));
1968                 RETURN;
1969             }
1970             {                   /* ## Mixed IV,UV ## */
1971                 IV iv;
1972                 UV uv;
1973                 
1974                 /* != is commutative so swap if needed (save code) */
1975                 if (auvok) {
1976                     /* swap. top of stack (b) is the iv */
1977                     iv = SvIVX(TOPs);
1978                     SP--;
1979                     if (iv < 0) {
1980                         /* As (a) is a UV, it's >0, so it cannot be == */
1981                         SETs(&PL_sv_yes);
1982                         RETURN;
1983                     }
1984                     uv = SvUVX(TOPs);
1985                 } else {
1986                     iv = SvIVX(TOPm1s);
1987                     SP--;
1988                     if (iv < 0) {
1989                         /* As (b) is a UV, it's >0, so it cannot be == */
1990                         SETs(&PL_sv_yes);
1991                         RETURN;
1992                     }
1993                     uv = SvUVX(*(SP+1)); /* Do I want TOPp1s() ? */
1994                 }
1995                 SETs(boolSV((UV)iv != uv));
1996                 RETURN;
1997             }
1998         }
1999     }
2000 #endif
2001     {
2002       dPOPnv;
2003       SETs(boolSV(TOPn != value));
2004       RETURN;
2005     }
2006 }
2007
2008 PP(pp_ncmp)
2009 {
2010     dVAR; dSP; dTARGET; tryAMAGICbin(ncmp,0);
2011 #ifndef NV_PRESERVES_UV
2012     if (SvROK(TOPs) && !SvAMAGIC(TOPs) && SvROK(TOPm1s) && !SvAMAGIC(TOPm1s)) {
2013         const UV right = PTR2UV(SvRV(POPs));
2014         const UV left = PTR2UV(SvRV(TOPs));
2015         SETi((left > right) - (left < right));
2016         RETURN;
2017     }
2018 #endif
2019 #ifdef PERL_PRESERVE_IVUV
2020     /* Fortunately it seems NaN isn't IOK */
2021     SvIV_please(TOPs);
2022     if (SvIOK(TOPs)) {
2023         SvIV_please(TOPm1s);
2024         if (SvIOK(TOPm1s)) {
2025             const bool leftuvok = SvUOK(TOPm1s);
2026             const bool rightuvok = SvUOK(TOPs);
2027             I32 value;
2028             if (!leftuvok && !rightuvok) { /* ## IV <=> IV ## */
2029                 const IV leftiv = SvIVX(TOPm1s);
2030                 const IV rightiv = SvIVX(TOPs);
2031                 
2032                 if (leftiv > rightiv)
2033                     value = 1;
2034                 else if (leftiv < rightiv)
2035                     value = -1;
2036                 else
2037                     value = 0;
2038             } else if (leftuvok && rightuvok) { /* ## UV <=> UV ## */
2039                 const UV leftuv = SvUVX(TOPm1s);
2040                 const UV rightuv = SvUVX(TOPs);
2041                 
2042                 if (leftuv > rightuv)
2043                     value = 1;
2044                 else if (leftuv < rightuv)
2045                     value = -1;
2046                 else
2047                     value = 0;
2048             } else if (leftuvok) { /* ## UV <=> IV ## */
2049                 const IV rightiv = SvIVX(TOPs);
2050                 if (rightiv < 0) {
2051                     /* As (a) is a UV, it's >=0, so it cannot be < */
2052                     value = 1;
2053                 } else {
2054                     const UV leftuv = SvUVX(TOPm1s);
2055                     if (leftuv > (UV)rightiv) {
2056                         value = 1;
2057                     } else if (leftuv < (UV)rightiv) {
2058                         value = -1;
2059                     } else {
2060                         value = 0;
2061                     }
2062                 }
2063             } else { /* ## IV <=> UV ## */
2064                 const IV leftiv = SvIVX(TOPm1s);
2065                 if (leftiv < 0) {
2066                     /* As (b) is a UV, it's >=0, so it must be < */
2067                     value = -1;
2068                 } else {
2069                     const UV rightuv = SvUVX(TOPs);
2070                     if ((UV)leftiv > rightuv) {
2071                         value = 1;
2072                     } else if ((UV)leftiv < rightuv) {
2073                         value = -1;
2074                     } else {
2075                         value = 0;
2076                     }
2077                 }
2078             }
2079             SP--;
2080             SETi(value);
2081             RETURN;
2082         }
2083     }
2084 #endif
2085     {
2086       dPOPTOPnnrl;
2087       I32 value;
2088
2089 #ifdef Perl_isnan
2090       if (Perl_isnan(left) || Perl_isnan(right)) {
2091           SETs(&PL_sv_undef);
2092           RETURN;
2093        }
2094       value = (left > right) - (left < right);
2095 #else
2096       if (left == right)
2097         value = 0;
2098       else if (left < right)
2099         value = -1;
2100       else if (left > right)
2101         value = 1;
2102       else {
2103         SETs(&PL_sv_undef);
2104         RETURN;
2105       }
2106 #endif
2107       SETi(value);
2108       RETURN;
2109     }
2110 }
2111
2112 PP(pp_sle)
2113 {
2114     dVAR; dSP;
2115
2116     int amg_type = sle_amg;
2117     int multiplier = 1;
2118     int rhs = 1;
2119
2120     switch (PL_op->op_type) {
2121     case OP_SLT:
2122         amg_type = slt_amg;
2123         /* cmp < 0 */
2124         rhs = 0;
2125         break;
2126     case OP_SGT:
2127         amg_type = sgt_amg;
2128         /* cmp > 0 */
2129         multiplier = -1;
2130         rhs = 0;
2131         break;
2132     case OP_SGE:
2133         amg_type = sge_amg;
2134         /* cmp >= 0 */
2135         multiplier = -1;
2136         break;
2137     }
2138
2139     tryAMAGICbinSET_var(amg_type,0);
2140     {
2141       dPOPTOPssrl;
2142       const int cmp = (IN_LOCALE_RUNTIME
2143                  ? sv_cmp_locale(left, right)
2144                  : sv_cmp(left, right));
2145       SETs(boolSV(cmp * multiplier < rhs));
2146       RETURN;
2147     }
2148 }
2149
2150 PP(pp_seq)
2151 {
2152     dVAR; dSP; tryAMAGICbinSET(seq,0);
2153     {
2154       dPOPTOPssrl;
2155       SETs(boolSV(sv_eq(left, right)));
2156       RETURN;
2157     }
2158 }
2159
2160 PP(pp_sne)
2161 {
2162     dVAR; dSP; tryAMAGICbinSET(sne,0);
2163     {
2164       dPOPTOPssrl;
2165       SETs(boolSV(!sv_eq(left, right)));
2166       RETURN;
2167     }
2168 }
2169
2170 PP(pp_scmp)
2171 {
2172     dVAR; dSP; dTARGET;  tryAMAGICbin(scmp,0);
2173     {
2174       dPOPTOPssrl;
2175       const int cmp = (IN_LOCALE_RUNTIME
2176                  ? sv_cmp_locale(left, right)
2177                  : sv_cmp(left, right));
2178       SETi( cmp );
2179       RETURN;
2180     }
2181 }
2182
2183 PP(pp_bit_and)
2184 {
2185     dVAR; dSP; dATARGET; tryAMAGICbin(band,opASSIGN);
2186     {
2187       dPOPTOPssrl;
2188       SvGETMAGIC(left);
2189       SvGETMAGIC(right);
2190       if (SvNIOKp(left) || SvNIOKp(right)) {
2191         if (PL_op->op_private & HINT_INTEGER) {
2192           const IV i = SvIV_nomg(left) & SvIV_nomg(right);
2193           SETi(i);
2194         }
2195         else {
2196           const UV u = SvUV_nomg(left) & SvUV_nomg(right);
2197           SETu(u);
2198         }
2199       }
2200       else {
2201         do_vop(PL_op->op_type, TARG, left, right);
2202         SETTARG;
2203       }
2204       RETURN;
2205     }
2206 }
2207
2208 PP(pp_bit_or)
2209 {
2210     dVAR; dSP; dATARGET;
2211     const int op_type = PL_op->op_type;
2212
2213     tryAMAGICbin_var((op_type == OP_BIT_OR ? bor_amg : bxor_amg), opASSIGN);
2214     {
2215       dPOPTOPssrl;
2216       SvGETMAGIC(left);
2217       SvGETMAGIC(right);
2218       if (SvNIOKp(left) || SvNIOKp(right)) {
2219         if (PL_op->op_private & HINT_INTEGER) {
2220           const IV l = (USE_LEFT(left) ? SvIV_nomg(left) : 0);
2221           const IV r = SvIV_nomg(right);
2222           const IV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
2223           SETi(result);
2224         }
2225         else {
2226           const UV l = (USE_LEFT(left) ? SvUV_nomg(left) : 0);
2227           const UV r = SvUV_nomg(right);
2228           const UV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
2229           SETu(result);
2230         }
2231       }
2232       else {
2233         do_vop(op_type, TARG, left, right);
2234         SETTARG;
2235       }
2236       RETURN;
2237     }
2238 }
2239
2240 PP(pp_negate)
2241 {
2242     dVAR; dSP; dTARGET; tryAMAGICun(neg);
2243     {
2244         dTOPss;
2245         const int flags = SvFLAGS(sv);
2246         SvGETMAGIC(sv);
2247         if ((flags & SVf_IOK) || ((flags & (SVp_IOK | SVp_NOK)) == SVp_IOK)) {
2248             /* It's publicly an integer, or privately an integer-not-float */
2249         oops_its_an_int:
2250             if (SvIsUV(sv)) {
2251                 if (SvIVX(sv) == IV_MIN) {
2252                     /* 2s complement assumption. */
2253                     SETi(SvIVX(sv));    /* special case: -((UV)IV_MAX+1) == IV_MIN */
2254                     RETURN;
2255                 }
2256                 else if (SvUVX(sv) <= IV_MAX) {
2257                     SETi(-SvIVX(sv));
2258                     RETURN;
2259                 }
2260             }
2261             else if (SvIVX(sv) != IV_MIN) {
2262                 SETi(-SvIVX(sv));
2263                 RETURN;
2264             }
2265 #ifdef PERL_PRESERVE_IVUV
2266             else {
2267                 SETu((UV)IV_MIN);
2268                 RETURN;
2269             }
2270 #endif
2271         }
2272         if (SvNIOKp(sv))
2273             SETn(-SvNV(sv));
2274         else if (SvPOKp(sv)) {
2275             STRLEN len;
2276             const char * const s = SvPV_const(sv, len);
2277             if (isIDFIRST(*s)) {
2278                 sv_setpvn(TARG, "-", 1);
2279                 sv_catsv(TARG, sv);
2280             }
2281             else if (*s == '+' || *s == '-') {
2282                 sv_setsv(TARG, sv);
2283                 *SvPV_force(TARG, len) = *s == '-' ? '+' : '-';
2284             }
2285             else if (DO_UTF8(sv)) {
2286                 SvIV_please(sv);
2287                 if (SvIOK(sv))
2288                     goto oops_its_an_int;
2289                 if (SvNOK(sv))
2290                     sv_setnv(TARG, -SvNV(sv));
2291                 else {
2292                     sv_setpvn(TARG, "-", 1);
2293                     sv_catsv(TARG, sv);
2294                 }
2295             }
2296             else {
2297                 SvIV_please(sv);
2298                 if (SvIOK(sv))
2299                   goto oops_its_an_int;
2300                 sv_setnv(TARG, -SvNV(sv));
2301             }
2302             SETTARG;
2303         }
2304         else
2305             SETn(-SvNV(sv));
2306     }
2307     RETURN;
2308 }
2309
2310 PP(pp_not)
2311 {
2312     dVAR; dSP; tryAMAGICunSET(not);
2313     *PL_stack_sp = boolSV(!SvTRUE(*PL_stack_sp));
2314     return NORMAL;
2315 }
2316
2317 PP(pp_complement)
2318 {
2319     dVAR; dSP; dTARGET; tryAMAGICun(compl);
2320     {
2321       dTOPss;
2322       SvGETMAGIC(sv);
2323       if (SvNIOKp(sv)) {
2324         if (PL_op->op_private & HINT_INTEGER) {
2325           const IV i = ~SvIV_nomg(sv);
2326           SETi(i);
2327         }
2328         else {
2329           const UV u = ~SvUV_nomg(sv);
2330           SETu(u);
2331         }
2332       }
2333       else {
2334         register U8 *tmps;
2335         register I32 anum;
2336         STRLEN len;
2337
2338         (void)SvPV_nomg_const(sv,len); /* force check for uninit var */
2339         sv_setsv_nomg(TARG, sv);
2340         tmps = (U8*)SvPV_force(TARG, len);
2341         anum = len;
2342         if (SvUTF8(TARG)) {
2343           /* Calculate exact length, let's not estimate. */
2344           STRLEN targlen = 0;
2345           U8 *result;
2346           U8 *send;
2347           STRLEN l;
2348           UV nchar = 0;
2349           UV nwide = 0;
2350
2351           send = tmps + len;
2352           while (tmps < send) {
2353             const UV c = utf8n_to_uvchr(tmps, send-tmps, &l, UTF8_ALLOW_ANYUV);
2354             tmps += UTF8SKIP(tmps);
2355             targlen += UNISKIP(~c);
2356             nchar++;
2357             if (c > 0xff)
2358                 nwide++;
2359           }
2360
2361           /* Now rewind strings and write them. */
2362           tmps -= len;
2363
2364           if (nwide) {
2365               Newxz(result, targlen + 1, U8);
2366               while (tmps < send) {
2367                   const UV c = utf8n_to_uvchr(tmps, send-tmps, &l, UTF8_ALLOW_ANYUV);
2368                   tmps += UTF8SKIP(tmps);
2369                   result = uvchr_to_utf8_flags(result, ~c, UNICODE_ALLOW_ANY);
2370               }
2371               *result = '\0';
2372               result -= targlen;
2373               sv_setpvn(TARG, (char*)result, targlen);
2374               SvUTF8_on(TARG);
2375           }
2376           else {
2377               Newxz(result, nchar + 1, U8);
2378               while (tmps < send) {
2379                   const U8 c = (U8)utf8n_to_uvchr(tmps, 0, &l, UTF8_ALLOW_ANY);
2380                   tmps += UTF8SKIP(tmps);
2381                   *result++ = ~c;
2382               }
2383               *result = '\0';
2384               result -= nchar;
2385               sv_setpvn(TARG, (char*)result, nchar);
2386               SvUTF8_off(TARG);
2387           }
2388           Safefree(result);
2389           SETs(TARG);
2390           RETURN;
2391         }
2392 #ifdef LIBERAL
2393         {
2394             register long *tmpl;
2395             for ( ; anum && (unsigned long)tmps % sizeof(long); anum--, tmps++)
2396                 *tmps = ~*tmps;
2397             tmpl = (long*)tmps;
2398             for ( ; anum >= sizeof(long); anum -= sizeof(long), tmpl++)
2399                 *tmpl = ~*tmpl;
2400             tmps = (U8*)tmpl;
2401         }
2402 #endif
2403         for ( ; anum > 0; anum--, tmps++)
2404             *tmps = ~*tmps;
2405
2406         SETs(TARG);
2407       }
2408       RETURN;
2409     }
2410 }
2411
2412 /* integer versions of some of the above */
2413
2414 PP(pp_i_multiply)
2415 {
2416     dVAR; dSP; dATARGET; tryAMAGICbin(mult,opASSIGN);
2417     {
2418       dPOPTOPiirl;
2419       SETi( left * right );
2420       RETURN;
2421     }
2422 }
2423
2424 PP(pp_i_divide)
2425 {
2426     IV num;
2427     dVAR; dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
2428     {
2429       dPOPiv;
2430       if (value == 0)
2431           DIE(aTHX_ "Illegal division by zero");
2432       num = POPi;
2433       if (num == IV_MIN && value == -1)
2434           DIE(aTHX_ "Integer overflow in division");
2435       value = num / value;
2436       PUSHi( value );
2437       RETURN;
2438     }
2439 }
2440
2441 STATIC
2442 PP(pp_i_modulo_0)
2443 {
2444      /* This is the vanilla old i_modulo. */
2445      dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
2446      {
2447           dPOPTOPiirl;
2448           if (!right)
2449                DIE(aTHX_ "Illegal modulus zero");
2450           SETi( left % right );
2451           RETURN;
2452      }
2453 }
2454
2455 #if defined(__GLIBC__) && IVSIZE == 8
2456 STATIC
2457 PP(pp_i_modulo_1)
2458 {
2459      /* This is the i_modulo with the workaround for the _moddi3 bug
2460       * in (at least) glibc 2.2.5 (the PERL_ABS() the workaround).
2461       * See below for pp_i_modulo. */
2462      dVAR; dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
2463      {
2464           dPOPTOPiirl;
2465           if (!right)
2466                DIE(aTHX_ "Illegal modulus zero");
2467           SETi( left % PERL_ABS(right) );
2468           RETURN;
2469      }
2470 }
2471 #endif
2472
2473 PP(pp_i_modulo)
2474 {
2475      dVAR; dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
2476      {
2477           dPOPTOPiirl;
2478           if (!right)
2479                DIE(aTHX_ "Illegal modulus zero");
2480           /* The assumption is to use hereafter the old vanilla version... */
2481           PL_op->op_ppaddr =
2482                PL_ppaddr[OP_I_MODULO] =
2483                    Perl_pp_i_modulo_0;
2484           /* .. but if we have glibc, we might have a buggy _moddi3
2485            * (at least glicb 2.2.5 is known to have this bug), in other
2486            * words our integer modulus with negative quad as the second
2487            * argument might be broken.  Test for this and re-patch the
2488            * opcode dispatch table if that is the case, remembering to
2489            * also apply the workaround so that this first round works
2490            * right, too.  See [perl #9402] for more information. */
2491 #if defined(__GLIBC__) && IVSIZE == 8
2492           {
2493                IV l =   3;
2494                IV r = -10;
2495                /* Cannot do this check with inlined IV constants since
2496                 * that seems to work correctly even with the buggy glibc. */
2497                if (l % r == -3) {
2498                     /* Yikes, we have the bug.
2499                      * Patch in the workaround version. */
2500                     PL_op->op_ppaddr =
2501                          PL_ppaddr[OP_I_MODULO] =
2502                              &Perl_pp_i_modulo_1;
2503                     /* Make certain we work right this time, too. */
2504                     right = PERL_ABS(right);
2505                }
2506           }
2507 #endif
2508           SETi( left % right );
2509           RETURN;
2510      }
2511 }
2512
2513 PP(pp_i_add)
2514 {
2515     dVAR; dSP; dATARGET; tryAMAGICbin(add,opASSIGN);
2516     {
2517       dPOPTOPiirl_ul;
2518       SETi( left + right );
2519       RETURN;
2520     }
2521 }
2522
2523 PP(pp_i_subtract)
2524 {
2525     dVAR; dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN);
2526     {
2527       dPOPTOPiirl_ul;
2528       SETi( left - right );
2529       RETURN;
2530     }
2531 }
2532
2533 PP(pp_i_lt)
2534 {
2535     dVAR; dSP; tryAMAGICbinSET(lt,0);
2536     {
2537       dPOPTOPiirl;
2538       SETs(boolSV(left < right));
2539       RETURN;
2540     }
2541 }
2542
2543 PP(pp_i_gt)
2544 {
2545     dVAR; dSP; tryAMAGICbinSET(gt,0);
2546     {
2547       dPOPTOPiirl;
2548       SETs(boolSV(left > right));
2549       RETURN;
2550     }
2551 }
2552
2553 PP(pp_i_le)
2554 {
2555     dVAR; dSP; tryAMAGICbinSET(le,0);
2556     {
2557       dPOPTOPiirl;
2558       SETs(boolSV(left <= right));
2559       RETURN;
2560     }
2561 }
2562
2563 PP(pp_i_ge)
2564 {
2565     dVAR; dSP; tryAMAGICbinSET(ge,0);
2566     {
2567       dPOPTOPiirl;
2568       SETs(boolSV(left >= right));
2569       RETURN;
2570     }
2571 }
2572
2573 PP(pp_i_eq)
2574 {
2575     dVAR; dSP; tryAMAGICbinSET(eq,0);
2576     {
2577       dPOPTOPiirl;
2578       SETs(boolSV(left == right));
2579       RETURN;
2580     }
2581 }
2582
2583 PP(pp_i_ne)
2584 {
2585     dVAR; dSP; tryAMAGICbinSET(ne,0);
2586     {
2587       dPOPTOPiirl;
2588       SETs(boolSV(left != right));
2589       RETURN;
2590     }
2591 }
2592
2593 PP(pp_i_ncmp)
2594 {
2595     dVAR; dSP; dTARGET; tryAMAGICbin(ncmp,0);
2596     {
2597       dPOPTOPiirl;
2598       I32 value;
2599
2600       if (left > right)
2601         value = 1;
2602       else if (left < right)
2603         value = -1;
2604       else
2605         value = 0;
2606       SETi(value);
2607       RETURN;
2608     }
2609 }
2610
2611 PP(pp_i_negate)
2612 {
2613     dVAR; dSP; dTARGET; tryAMAGICun(neg);
2614     SETi(-TOPi);
2615     RETURN;
2616 }
2617
2618 /* High falutin' math. */
2619
2620 PP(pp_atan2)
2621 {
2622     dVAR; dSP; dTARGET; tryAMAGICbin(atan2,0);
2623     {
2624       dPOPTOPnnrl;
2625       SETn(Perl_atan2(left, right));
2626       RETURN;
2627     }
2628 }
2629
2630 PP(pp_sin)
2631 {
2632     dVAR; dSP; dTARGET;
2633     int amg_type = sin_amg;
2634     const char *neg_report = NULL;
2635     NV (*func)(NV) = Perl_sin;
2636     const int op_type = PL_op->op_type;
2637
2638     switch (op_type) {
2639     case OP_COS:
2640         amg_type = cos_amg;
2641         func = Perl_cos;
2642         break;
2643     case OP_EXP:
2644         amg_type = exp_amg;
2645         func = Perl_exp;
2646         break;
2647     case OP_LOG:
2648         amg_type = log_amg;
2649         func = Perl_log;
2650         neg_report = "log";
2651         break;
2652     case OP_SQRT:
2653         amg_type = sqrt_amg;
2654         func = Perl_sqrt;
2655         neg_report = "sqrt";
2656         break;
2657     }
2658
2659     tryAMAGICun_var(amg_type);
2660     {
2661       const NV value = POPn;
2662       if (neg_report) {
2663           if (op_type == OP_LOG ? (value <= 0.0) : (value < 0.0)) {
2664               SET_NUMERIC_STANDARD();
2665               DIE(aTHX_ "Can't take %s of %"NVgf, neg_report, value);
2666           }
2667       }
2668       XPUSHn(func(value));
2669       RETURN;
2670     }
2671 }
2672
2673 /* Support Configure command-line overrides for rand() functions.
2674    After 5.005, perhaps we should replace this by Configure support
2675    for drand48(), random(), or rand().  For 5.005, though, maintain
2676    compatibility by calling rand() but allow the user to override it.
2677    See INSTALL for details.  --Andy Dougherty  15 July 1998
2678 */
2679 /* Now it's after 5.005, and Configure supports drand48() and random(),
2680    in addition to rand().  So the overrides should not be needed any more.
2681    --Jarkko Hietaniemi  27 September 1998
2682  */
2683
2684 #ifndef HAS_DRAND48_PROTO
2685 extern double drand48 (void);
2686 #endif
2687
2688 PP(pp_rand)
2689 {
2690     dVAR; dSP; dTARGET;
2691     NV value;
2692     if (MAXARG < 1)
2693         value = 1.0;
2694     else
2695         value = POPn;
2696     if (value == 0.0)
2697         value = 1.0;
2698     if (!PL_srand_called) {
2699         (void)seedDrand01((Rand_seed_t)seed());
2700         PL_srand_called = TRUE;
2701     }
2702     value *= Drand01();
2703     XPUSHn(value);
2704     RETURN;
2705 }
2706
2707 PP(pp_srand)
2708 {
2709     dVAR; dSP;
2710     const UV anum = (MAXARG < 1) ? seed() : POPu;
2711     (void)seedDrand01((Rand_seed_t)anum);
2712     PL_srand_called = TRUE;
2713     EXTEND(SP, 1);
2714     RETPUSHYES;
2715 }
2716
2717 PP(pp_int)
2718 {
2719     dVAR; dSP; dTARGET; tryAMAGICun(int);
2720     {
2721       const IV iv = TOPi; /* attempt to convert to IV if possible. */
2722       /* XXX it's arguable that compiler casting to IV might be subtly
2723          different from modf (for numbers inside (IV_MIN,UV_MAX)) in which
2724          else preferring IV has introduced a subtle behaviour change bug. OTOH
2725          relying on floating point to be accurate is a bug.  */
2726
2727       if (!SvOK(TOPs))
2728         SETu(0);
2729       else if (SvIOK(TOPs)) {
2730         if (SvIsUV(TOPs)) {
2731             const UV uv = TOPu;
2732             SETu(uv);
2733         } else
2734             SETi(iv);
2735       } else {
2736           const NV value = TOPn;
2737           if (value >= 0.0) {
2738               if (value < (NV)UV_MAX + 0.5) {
2739                   SETu(U_V(value));
2740               } else {
2741                   SETn(Perl_floor(value));
2742               }
2743           }
2744           else {
2745               if (value > (NV)IV_MIN - 0.5) {
2746                   SETi(I_V(value));
2747               } else {
2748                   SETn(Perl_ceil(value));
2749               }
2750           }
2751       }
2752     }
2753     RETURN;
2754 }
2755
2756 PP(pp_abs)
2757 {
2758     dVAR; dSP; dTARGET; tryAMAGICun(abs);
2759     {
2760       /* This will cache the NV value if string isn't actually integer  */
2761       const IV iv = TOPi;
2762
2763       if (!SvOK(TOPs))
2764         SETu(0);
2765       else if (SvIOK(TOPs)) {
2766         /* IVX is precise  */
2767         if (SvIsUV(TOPs)) {
2768           SETu(TOPu);   /* force it to be numeric only */
2769         } else {
2770           if (iv >= 0) {
2771             SETi(iv);
2772           } else {
2773             if (iv != IV_MIN) {
2774               SETi(-iv);
2775             } else {
2776               /* 2s complement assumption. Also, not really needed as
2777                  IV_MIN and -IV_MIN should both be %100...00 and NV-able  */
2778               SETu(IV_MIN);
2779             }
2780           }
2781         }
2782       } else{
2783         const NV value = TOPn;
2784         if (value < 0.0)
2785           SETn(-value);
2786         else
2787           SETn(value);
2788       }
2789     }
2790     RETURN;
2791 }
2792
2793 PP(pp_oct)
2794 {
2795     dVAR; dSP; dTARGET;
2796     const char *tmps;
2797     I32 flags = PERL_SCAN_ALLOW_UNDERSCORES;
2798     STRLEN len;
2799     NV result_nv;
2800     UV result_uv;
2801     SV* const sv = POPs;
2802
2803     tmps = (SvPV_const(sv, len));
2804     if (DO_UTF8(sv)) {
2805          /* If Unicode, try to downgrade
2806           * If not possible, croak. */
2807          SV* const tsv = sv_2mortal(newSVsv(sv));
2808         
2809          SvUTF8_on(tsv);
2810          sv_utf8_downgrade(tsv, FALSE);
2811          tmps = SvPV_const(tsv, len);
2812     }
2813     if (PL_op->op_type == OP_HEX)
2814         goto hex;
2815
2816     while (*tmps && len && isSPACE(*tmps))
2817         tmps++, len--;
2818     if (*tmps == '0')
2819         tmps++, len--;
2820     if (*tmps == 'x') {
2821     hex:
2822         result_uv = grok_hex (tmps, &len, &flags, &result_nv);
2823     }
2824     else if (*tmps == 'b')
2825         result_uv = grok_bin (tmps, &len, &flags, &result_nv);
2826     else
2827         result_uv = grok_oct (tmps, &len, &flags, &result_nv);
2828
2829     if (flags & PERL_SCAN_GREATER_THAN_UV_MAX) {
2830         XPUSHn(result_nv);
2831     }
2832     else {
2833         XPUSHu(result_uv);
2834     }
2835     RETURN;
2836 }
2837
2838 /* String stuff. */
2839
2840 PP(pp_length)
2841 {
2842     dVAR; dSP; dTARGET;
2843     SV * const sv = TOPs;
2844
2845     if (DO_UTF8(sv))
2846         SETi(sv_len_utf8(sv));
2847     else
2848         SETi(sv_len(sv));
2849     RETURN;
2850 }
2851
2852 PP(pp_substr)
2853 {
2854     dVAR; dSP; dTARGET;
2855     SV *sv;
2856     I32 len = 0;
2857     STRLEN curlen;
2858     STRLEN utf8_curlen;
2859     I32 pos;
2860     I32 rem;
2861     I32 fail;
2862     const I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
2863     const char *tmps;
2864     const I32 arybase = PL_curcop->cop_arybase;
2865     SV *repl_sv = NULL;
2866     const char *repl = NULL;
2867     STRLEN repl_len;
2868     const int num_args = PL_op->op_private & 7;
2869     bool repl_need_utf8_upgrade = FALSE;
2870     bool repl_is_utf8 = FALSE;
2871
2872     SvTAINTED_off(TARG);                        /* decontaminate */
2873     SvUTF8_off(TARG);                           /* decontaminate */
2874     if (num_args > 2) {
2875         if (num_args > 3) {
2876             repl_sv = POPs;
2877             repl = SvPV_const(repl_sv, repl_len);
2878             repl_is_utf8 = DO_UTF8(repl_sv) && SvCUR(repl_sv);
2879         }
2880         len = POPi;
2881     }
2882     pos = POPi;
2883     sv = POPs;
2884     PUTBACK;
2885     if (repl_sv) {
2886         if (repl_is_utf8) {
2887             if (!DO_UTF8(sv))
2888                 sv_utf8_upgrade(sv);
2889         }
2890         else if (DO_UTF8(sv))
2891             repl_need_utf8_upgrade = TRUE;
2892     }
2893     tmps = SvPV_const(sv, curlen);
2894     if (DO_UTF8(sv)) {
2895         utf8_curlen = sv_len_utf8(sv);
2896         if (utf8_curlen == curlen)
2897             utf8_curlen = 0;
2898         else
2899             curlen = utf8_curlen;
2900     }
2901     else
2902         utf8_curlen = 0;
2903
2904     if (pos >= arybase) {
2905         pos -= arybase;
2906         rem = curlen-pos;
2907         fail = rem;
2908         if (num_args > 2) {
2909             if (len < 0) {
2910                 rem += len;
2911                 if (rem < 0)
2912                     rem = 0;
2913             }
2914             else if (rem > len)
2915                      rem = len;
2916         }
2917     }
2918     else {
2919         pos += curlen;
2920         if (num_args < 3)
2921             rem = curlen;
2922         else if (len >= 0) {
2923             rem = pos+len;
2924             if (rem > (I32)curlen)
2925                 rem = curlen;
2926         }
2927         else {
2928             rem = curlen+len;
2929             if (rem < pos)
2930                 rem = pos;
2931         }
2932         if (pos < 0)
2933             pos = 0;
2934         fail = rem;
2935         rem -= pos;
2936     }
2937     if (fail < 0) {
2938         if (lvalue || repl)
2939             Perl_croak(aTHX_ "substr outside of string");
2940         if (ckWARN(WARN_SUBSTR))
2941             Perl_warner(aTHX_ packWARN(WARN_SUBSTR), "substr outside of string");
2942         RETPUSHUNDEF;
2943     }
2944     else {
2945         const I32 upos = pos;
2946         const I32 urem = rem;
2947         if (utf8_curlen)
2948             sv_pos_u2b(sv, &pos, &rem);
2949         tmps += pos;
2950         /* we either return a PV or an LV. If the TARG hasn't been used
2951          * before, or is of that type, reuse it; otherwise use a mortal
2952          * instead. Note that LVs can have an extended lifetime, so also
2953          * dont reuse if refcount > 1 (bug #20933) */
2954         if (SvTYPE(TARG) > SVt_NULL) {
2955             if ( (SvTYPE(TARG) == SVt_PVLV)
2956                     ? (!lvalue || SvREFCNT(TARG) > 1)
2957                     : lvalue)
2958             {
2959                 TARG = sv_newmortal();
2960             }
2961         }
2962
2963         sv_setpvn(TARG, tmps, rem);
2964 #ifdef USE_LOCALE_COLLATE
2965         sv_unmagic(TARG, PERL_MAGIC_collxfrm);
2966 #endif
2967         if (utf8_curlen)
2968             SvUTF8_on(TARG);
2969         if (repl) {
2970             SV* repl_sv_copy = NULL;
2971
2972             if (repl_need_utf8_upgrade) {
2973                 repl_sv_copy = newSVsv(repl_sv);
2974                 sv_utf8_upgrade(repl_sv_copy);
2975                 repl = SvPV_const(repl_sv_copy, repl_len);
2976                 repl_is_utf8 = DO_UTF8(repl_sv_copy) && SvCUR(sv);
2977             }
2978             sv_insert(sv, pos, rem, repl, repl_len);
2979             if (repl_is_utf8)
2980                 SvUTF8_on(sv);
2981             if (repl_sv_copy)
2982                 SvREFCNT_dec(repl_sv_copy);
2983         }
2984         else if (lvalue) {              /* it's an lvalue! */
2985             if (!SvGMAGICAL(sv)) {
2986                 if (SvROK(sv)) {
2987                     SvPV_force_nolen(sv);
2988                     if (ckWARN(WARN_SUBSTR))
2989                         Perl_warner(aTHX_ packWARN(WARN_SUBSTR),
2990                                 "Attempt to use reference as lvalue in substr");
2991                 }
2992                 if (SvOK(sv))           /* is it defined ? */
2993                     (void)SvPOK_only_UTF8(sv);
2994                 else
2995                     sv_setpvn(sv,"",0); /* avoid lexical reincarnation */
2996             }
2997
2998             if (SvTYPE(TARG) < SVt_PVLV) {
2999                 sv_upgrade(TARG, SVt_PVLV);
3000                 sv_magic(TARG, NULL, PERL_MAGIC_substr, NULL, 0);
3001             }
3002             else
3003                 SvOK_off(TARG);
3004
3005             LvTYPE(TARG) = 'x';
3006             if (LvTARG(TARG) != sv) {
3007                 if (LvTARG(TARG))
3008                     SvREFCNT_dec(LvTARG(TARG));
3009                 LvTARG(TARG) = SvREFCNT_inc(sv);
3010             }
3011             LvTARGOFF(TARG) = upos;
3012             LvTARGLEN(TARG) = urem;
3013         }
3014     }
3015     SPAGAIN;
3016     PUSHs(TARG);                /* avoid SvSETMAGIC here */
3017     RETURN;
3018 }
3019
3020 PP(pp_vec)
3021 {
3022     dVAR; dSP; dTARGET;
3023     register const IV size   = POPi;
3024     register const IV offset = POPi;
3025     register SV * const src = POPs;
3026     const I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
3027
3028     SvTAINTED_off(TARG);                /* decontaminate */
3029     if (lvalue) {                       /* it's an lvalue! */
3030         if (SvREFCNT(TARG) > 1) /* don't share the TARG (#20933) */
3031             TARG = sv_newmortal();
3032         if (SvTYPE(TARG) < SVt_PVLV) {
3033             sv_upgrade(TARG, SVt_PVLV);
3034             sv_magic(TARG, NULL, PERL_MAGIC_vec, NULL, 0);
3035         }
3036         LvTYPE(TARG) = 'v';
3037         if (LvTARG(TARG) != src) {
3038             if (LvTARG(TARG))
3039                 SvREFCNT_dec(LvTARG(TARG));
3040             LvTARG(TARG) = SvREFCNT_inc(src);
3041         }
3042         LvTARGOFF(TARG) = offset;
3043         LvTARGLEN(TARG) = size;
3044     }
3045
3046     sv_setuv(TARG, do_vecget(src, offset, size));
3047     PUSHs(TARG);
3048     RETURN;
3049 }
3050
3051 PP(pp_index)
3052 {
3053     dVAR; dSP; dTARGET;
3054     SV *big;
3055     SV *little;
3056     SV *temp = NULL;
3057     STRLEN biglen;
3058     STRLEN llen = 0;
3059     I32 offset;
3060     I32 retval;
3061     const char *tmps;
3062     const char *tmps2;
3063     const I32 arybase = PL_curcop->cop_arybase;
3064     bool big_utf8;
3065     bool little_utf8;
3066     const bool is_index = PL_op->op_type == OP_INDEX;
3067
3068     if (MAXARG >= 3) {
3069         /* arybase is in characters, like offset, so combine prior to the
3070            UTF-8 to bytes calculation.  */
3071         offset = POPi - arybase;
3072     }
3073     little = POPs;
3074     big = POPs;
3075     big_utf8 = DO_UTF8(big);
3076     little_utf8 = DO_UTF8(little);
3077     if (big_utf8 ^ little_utf8) {
3078         /* One needs to be upgraded.  */
3079         if (little_utf8 && !PL_encoding) {
3080             /* Well, maybe instead we might be able to downgrade the small
3081                string?  */
3082             STRLEN little_len;
3083             const U8 * const little_pv = (U8*) SvPV_const(little, little_len);
3084             char * const pv = (char*)bytes_from_utf8(little_pv, &little_len,
3085                                                      &little_utf8);
3086             if (little_utf8) {
3087                 /* If the large string is ISO-8859-1, and it's not possible to
3088                    convert the small string to ISO-8859-1, then there is no
3089                    way that it could be found anywhere by index.  */
3090                 retval = -1;
3091                 goto fail;
3092             }
3093
3094             /* At this point, pv is a malloc()ed string. So donate it to temp
3095                to ensure it will get free()d  */
3096             little = temp = newSV(0);
3097             sv_usepvn(temp, pv, little_len);
3098         } else {
3099             SV * const bytes = little_utf8 ? big : little;
3100             STRLEN len;
3101             const char * const p = SvPV_const(bytes, len);
3102
3103             temp = newSVpvn(p, len);
3104
3105             if (PL_encoding) {
3106                 sv_recode_to_utf8(temp, PL_encoding);
3107             } else {
3108                 sv_utf8_upgrade(temp);
3109             }
3110             if (little_utf8) {
3111                 big = temp;
3112                 big_utf8 = TRUE;
3113             } else {
3114                 little = temp;
3115             }
3116         }
3117     }
3118     /* Don't actually need the NULL initialisation, but it keeps gcc quiet.  */
3119     tmps2 = is_index ? NULL : SvPV_const(little, llen);
3120     tmps = SvPV_const(big, biglen);
3121
3122     if (MAXARG < 3)
3123         offset = is_index ? 0 : biglen;
3124     else {
3125         if (big_utf8 && offset > 0)
3126             sv_pos_u2b(big, &offset, 0);
3127         offset += llen;
3128     }
3129     if (offset < 0)
3130         offset = 0;
3131     else if (offset > (I32)biglen)
3132         offset = biglen;
3133     if (!(tmps2 = is_index
3134           ? fbm_instr((unsigned char*)tmps + offset,
3135                       (unsigned char*)tmps + biglen, little, 0)
3136           : rninstr(tmps,  tmps  + offset,
3137                     tmps2, tmps2 + llen)))
3138         retval = -1;
3139     else {
3140         retval = tmps2 - tmps;
3141         if (retval > 0 && big_utf8)
3142             sv_pos_b2u(big, &retval);
3143     }
3144     if (temp)
3145         SvREFCNT_dec(temp);
3146  fail:
3147     PUSHi(retval + arybase);
3148     RETURN;
3149 }
3150
3151 PP(pp_sprintf)
3152 {
3153     dVAR; dSP; dMARK; dORIGMARK; dTARGET;
3154     do_sprintf(TARG, SP-MARK, MARK+1);
3155     TAINT_IF(SvTAINTED(TARG));
3156     SP = ORIGMARK;
3157     PUSHTARG;
3158     RETURN;
3159 }
3160
3161 PP(pp_ord)
3162 {
3163     dVAR; dSP; dTARGET;
3164     SV *argsv = POPs;
3165     STRLEN len;
3166     const U8 *s = (U8*)SvPV_const(argsv, len);
3167     SV *tmpsv;
3168
3169     if (PL_encoding && SvPOK(argsv) && !DO_UTF8(argsv)) {
3170         tmpsv = sv_2mortal(newSVsv(argsv));
3171         s = (U8*)sv_recode_to_utf8(tmpsv, PL_encoding);
3172         argsv = tmpsv;
3173     }
3174
3175     XPUSHu(DO_UTF8(argsv) ?
3176            utf8n_to_uvchr(s, UTF8_MAXBYTES, 0, UTF8_ALLOW_ANYUV) :
3177            (*s & 0xff));
3178
3179     RETURN;
3180 }
3181
3182 PP(pp_chr)
3183 {
3184     dVAR; dSP; dTARGET;
3185     char *tmps;
3186     UV value;
3187
3188     if (((SvIOK_notUV(TOPs) && SvIV(TOPs) < 0)
3189          ||
3190          (SvNOK(TOPs) && SvNV(TOPs) < 0.0))) {
3191         if (IN_BYTES) {
3192             value = POPu; /* chr(-1) eq chr(0xff), etc. */
3193         } else {
3194             (void) POPs; /* Ignore the argument value. */
3195             value = UNICODE_REPLACEMENT;
3196         }
3197     } else {
3198         value = POPu;
3199     }
3200
3201     SvUPGRADE(TARG,SVt_PV);
3202
3203     if (value > 255 && !IN_BYTES) {
3204         SvGROW(TARG, (STRLEN)UNISKIP(value)+1);
3205         tmps = (char*)uvchr_to_utf8_flags((U8*)SvPVX(TARG), value, 0);
3206         SvCUR_set(TARG, tmps - SvPVX_const(TARG));
3207         *tmps = '\0';
3208         (void)SvPOK_only(TARG);
3209         SvUTF8_on(TARG);
3210         XPUSHs(TARG);
3211         RETURN;
3212     }
3213
3214     SvGROW(TARG,2);
3215     SvCUR_set(TARG, 1);
3216     tmps = SvPVX(TARG);
3217     *tmps++ = (char)value;
3218     *tmps = '\0';
3219     (void)SvPOK_only(TARG);
3220     if (PL_encoding && !IN_BYTES) {
3221         sv_recode_to_utf8(TARG, PL_encoding);
3222         tmps = SvPVX(TARG);
3223         if (SvCUR(TARG) == 0 || !is_utf8_string((U8*)tmps, SvCUR(TARG)) ||
3224             memEQ(tmps, "\xef\xbf\xbd\0", 4)) {
3225             SvGROW(TARG, 3);
3226             tmps = SvPVX(TARG);
3227             SvCUR_set(TARG, 2);
3228             *tmps++ = (U8)UTF8_EIGHT_BIT_HI(value);
3229             *tmps++ = (U8)UTF8_EIGHT_BIT_LO(value);
3230             *tmps = '\0';
3231             SvUTF8_on(TARG);
3232         }
3233     }
3234     XPUSHs(TARG);
3235     RETURN;
3236 }
3237
3238 PP(pp_crypt)
3239 {
3240 #ifdef HAS_CRYPT
3241     dVAR; dSP; dTARGET;
3242     dPOPTOPssrl;
3243     STRLEN len;
3244     const char *tmps = SvPV_const(left, len);
3245
3246     if (DO_UTF8(left)) {
3247          /* If Unicode, try to downgrade.
3248           * If not possible, croak.
3249           * Yes, we made this up.  */
3250          SV* const tsv = sv_2mortal(newSVsv(left));
3251
3252          SvUTF8_on(tsv);
3253          sv_utf8_downgrade(tsv, FALSE);
3254          tmps = SvPV_const(tsv, len);
3255     }
3256 #   ifdef USE_ITHREADS
3257 #     ifdef HAS_CRYPT_R
3258     if (!PL_reentrant_buffer->_crypt_struct_buffer) {
3259       /* This should be threadsafe because in ithreads there is only
3260        * one thread per interpreter.  If this would not be true,
3261        * we would need a mutex to protect this malloc. */
3262         PL_reentrant_buffer->_crypt_struct_buffer =
3263           (struct crypt_data *)safemalloc(sizeof(struct crypt_data));
3264 #if defined(__GLIBC__) || defined(__EMX__)
3265         if (PL_reentrant_buffer->_crypt_struct_buffer) {
3266             PL_reentrant_buffer->_crypt_struct_buffer->initialized = 0;
3267             /* work around glibc-2.2.5 bug */
3268             PL_reentrant_buffer->_crypt_struct_buffer->current_saltbits = 0;
3269         }
3270 #endif
3271     }
3272 #     endif /* HAS_CRYPT_R */
3273 #   endif /* USE_ITHREADS */
3274 #   ifdef FCRYPT
3275     sv_setpv(TARG, fcrypt(tmps, SvPV_nolen_const(right)));
3276 #   else
3277     sv_setpv(TARG, PerlProc_crypt(tmps, SvPV_nolen_const(right)));
3278 #   endif
3279     SETs(TARG);
3280     RETURN;
3281 #else
3282     DIE(aTHX_
3283       "The crypt() function is unimplemented due to excessive paranoia.");
3284 #endif
3285 }
3286
3287 PP(pp_ucfirst)
3288 {
3289     dVAR;
3290     dSP;
3291     SV *sv = TOPs;
3292     const U8 *s;
3293     STRLEN slen;
3294     const int op_type = PL_op->op_type;
3295
3296     SvGETMAGIC(sv);
3297     if (DO_UTF8(sv) &&
3298         (s = (const U8*)SvPV_nomg_const(sv, slen)) && slen &&
3299         UTF8_IS_START(*s)) {
3300         U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
3301         STRLEN ulen;
3302         STRLEN tculen;
3303
3304         utf8_to_uvchr(s, &ulen);
3305         if (op_type == OP_UCFIRST) {
3306             toTITLE_utf8(s, tmpbuf, &tculen);
3307         } else {
3308             toLOWER_utf8(s, tmpbuf, &tculen);
3309         }
3310
3311         if (!SvPADTMP(sv) || SvREADONLY(sv) || ulen != tculen) {
3312             dTARGET;
3313             /* slen is the byte length of the whole SV.
3314              * ulen is the byte length of the original Unicode character
3315              * stored as UTF-8 at s.
3316              * tculen is the byte length of the freshly titlecased (or
3317              * lowercased) Unicode character stored as UTF-8 at tmpbuf.
3318              * We first set the result to be the titlecased (/lowercased)
3319              * character, and then append the rest of the SV data. */
3320             sv_setpvn(TARG, (char*)tmpbuf, tculen);
3321             if (slen > ulen)
3322                 sv_catpvn(TARG, (char*)(s + ulen), slen - ulen);
3323             SvUTF8_on(TARG);
3324             SETs(TARG);
3325         }
3326         else {
3327             s = (U8*)SvPV_force_nomg(sv, slen);
3328             Copy(tmpbuf, s, tculen, U8);
3329         }
3330     }
3331     else {
3332         U8 *s1;
3333         if (!SvPADTMP(sv) || SvREADONLY(sv)) {
3334             dTARGET;
3335             SvUTF8_off(TARG);                           /* decontaminate */
3336             sv_setsv_nomg(TARG, sv);
3337             sv = TARG;
3338             SETs(sv);
3339         }
3340         s1 = (U8*)SvPV_force_nomg(sv, slen);
3341         if (*s1) {
3342             if (IN_LOCALE_RUNTIME) {
3343                 TAINT;
3344                 SvTAINTED_on(sv);
3345                 *s1 = (op_type == OP_UCFIRST)
3346                     ? toUPPER_LC(*s1) : toLOWER_LC(*s1);
3347             }
3348             else
3349                 *s1 = (op_type == OP_UCFIRST) ? toUPPER(*s1) : toLOWER(*s1);
3350         }
3351     }
3352     SvSETMAGIC(sv);
3353     RETURN;
3354 }
3355
3356 PP(pp_uc)
3357 {
3358     dVAR;
3359     dSP;
3360     SV *sv = TOPs;
3361     STRLEN len;
3362
3363     SvGETMAGIC(sv);
3364     if (DO_UTF8(sv)) {
3365         dTARGET;
3366         STRLEN ulen;
3367         register U8 *d;
3368         const U8 *s;
3369         const U8 *send;
3370         U8 tmpbuf[UTF8_MAXBYTES+1];
3371
3372         s = (const U8*)SvPV_nomg_const(sv,len);
3373         if (!len) {
3374             SvUTF8_off(TARG);                           /* decontaminate */
3375             sv_setpvn(TARG, "", 0);
3376             SETs(TARG);
3377         }
3378         else {
3379             STRLEN min = len + 1;
3380
3381             SvUPGRADE(TARG, SVt_PV);
3382             SvGROW(TARG, min);
3383             (void)SvPOK_only(TARG);
3384             d = (U8*)SvPVX(TARG);
3385             send = s + len;
3386             while (s < send) {
3387                 STRLEN u = UTF8SKIP(s);
3388
3389                 toUPPER_utf8(s, tmpbuf, &ulen);
3390                 if (ulen > u && (SvLEN(TARG) < (min += ulen - u))) {
3391                     /* If the eventually required minimum size outgrows
3392                      * the available space, we need to grow. */
3393                     const UV o = d - (U8*)SvPVX_const(TARG);
3394
3395                     /* If someone uppercases one million U+03B0s we
3396                      * SvGROW() one million times.  Or we could try
3397                      * guessing how much to allocate without allocating
3398                      * too much. Such is life. */
3399                     SvGROW(TARG, min);
3400                     d = (U8*)SvPVX(TARG) + o;
3401                 }
3402                 Copy(tmpbuf, d, ulen, U8);
3403                 d += ulen;
3404                 s += u;
3405             }
3406             *d = '\0';
3407             SvUTF8_on(TARG);
3408             SvCUR_set(TARG, d - (U8*)SvPVX_const(TARG));
3409             SETs(TARG);
3410         }
3411     }
3412     else {
3413         U8 *s;
3414         if (!SvPADTMP(sv) || SvREADONLY(sv)) {
3415             dTARGET;
3416             SvUTF8_off(TARG);                           /* decontaminate */
3417             sv_setsv_nomg(TARG, sv);
3418             sv = TARG;
3419             SETs(sv);
3420         }
3421         s = (U8*)SvPV_force_nomg(sv, len);
3422         if (len) {
3423             register const U8 *send = s + len;
3424
3425             if (IN_LOCALE_RUNTIME) {
3426                 TAINT;
3427                 SvTAINTED_on(sv);
3428                 for (; s < send; s++)
3429                     *s = toUPPER_LC(*s);
3430             }
3431             else {
3432                 for (; s < send; s++)
3433                     *s = toUPPER(*s);
3434             }
3435         }
3436     }
3437     SvSETMAGIC(sv);
3438     RETURN;
3439 }
3440
3441 PP(pp_lc)
3442 {
3443     dVAR;
3444     dSP;
3445     SV *sv = TOPs;
3446     STRLEN len;
3447
3448     SvGETMAGIC(sv);
3449     if (DO_UTF8(sv)) {
3450         dTARGET;
3451         const U8 *s;
3452         STRLEN ulen;
3453         register U8 *d;
3454         const U8 *send;
3455         U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
3456
3457         s = (const U8*)SvPV_nomg_const(sv,len);
3458         if (!len) {
3459             SvUTF8_off(TARG);                           /* decontaminate */
3460             sv_setpvn(TARG, "", 0);
3461             SETs(TARG);
3462         }
3463         else {
3464             STRLEN min = len + 1;
3465
3466             SvUPGRADE(TARG, SVt_PV);
3467             SvGROW(TARG, min);
3468             (void)SvPOK_only(TARG);
3469             d = (U8*)SvPVX(TARG);
3470             send = s + len;
3471             while (s < send) {
3472                 const STRLEN u = UTF8SKIP(s);
3473                 const UV uv = toLOWER_utf8(s, tmpbuf, &ulen);
3474
3475 #define GREEK_CAPITAL_LETTER_SIGMA 0x03A3 /* Unicode U+03A3 */
3476                 if (uv == GREEK_CAPITAL_LETTER_SIGMA) {
3477                      /*
3478                       * Now if the sigma is NOT followed by
3479                       * /$ignorable_sequence$cased_letter/;
3480                       * and it IS preceded by
3481                       * /$cased_letter$ignorable_sequence/;
3482                       * where $ignorable_sequence is
3483                       * [\x{2010}\x{AD}\p{Mn}]*
3484                       * and $cased_letter is
3485                       * [\p{Ll}\p{Lo}\p{Lt}]
3486                       * then it should be mapped to 0x03C2,
3487                       * (GREEK SMALL LETTER FINAL SIGMA),
3488                       * instead of staying 0x03A3.
3489                       * "should be": in other words,
3490                       * this is not implemented yet.
3491                       * See lib/unicore/SpecialCasing.txt.
3492                       */
3493                 }
3494                 if (ulen > u && (SvLEN(TARG) < (min += ulen - u))) {
3495                     /* If the eventually required minimum size outgrows
3496                      * the available space, we need to grow. */
3497                     const UV o = d - (U8*)SvPVX_const(TARG);
3498
3499                     /* If someone lowercases one million U+0130s we
3500                      * SvGROW() one million times.  Or we could try
3501                      * guessing how much to allocate without allocating.
3502                      * too much.  Such is life. */
3503                     SvGROW(TARG, min);
3504                     d = (U8*)SvPVX(TARG) + o;
3505                 }
3506                 Copy(tmpbuf, d, ulen, U8);
3507                 d += ulen;
3508                 s += u;
3509             }
3510             *d = '\0';
3511             SvUTF8_on(TARG);
3512             SvCUR_set(TARG, d - (U8*)SvPVX_const(TARG));
3513             SETs(TARG);
3514         }
3515     }
3516     else {
3517         U8 *s;
3518         if (!SvPADTMP(sv) || SvREADONLY(sv)) {
3519             dTARGET;
3520             SvUTF8_off(TARG);                           /* decontaminate */
3521             sv_setsv_nomg(TARG, sv);
3522             sv = TARG;
3523             SETs(sv);
3524         }
3525
3526         s = (U8*)SvPV_force_nomg(sv, len);
3527         if (len) {
3528             register const U8 * const send = s + len;
3529
3530             if (IN_LOCALE_RUNTIME) {
3531                 TAINT;
3532                 SvTAINTED_on(sv);
3533                 for (; s < send; s++)
3534                     *s = toLOWER_LC(*s);
3535             }
3536             else {
3537                 for (; s < send; s++)
3538                     *s = toLOWER(*s);
3539             }
3540         }
3541     }
3542     SvSETMAGIC(sv);
3543     RETURN;
3544 }
3545
3546 PP(pp_quotemeta)
3547 {
3548     dVAR; dSP; dTARGET;
3549     SV * const sv = TOPs;
3550     STRLEN len;
3551     register const char *s = SvPV_const(sv,len);
3552
3553     SvUTF8_off(TARG);                           /* decontaminate */
3554     if (len) {
3555         register char *d;
3556         SvUPGRADE(TARG, SVt_PV);
3557         SvGROW(TARG, (len * 2) + 1);
3558         d = SvPVX(TARG);
3559         if (DO_UTF8(sv)) {
3560             while (len) {
3561                 if (UTF8_IS_CONTINUED(*s)) {
3562                     STRLEN ulen = UTF8SKIP(s);
3563                     if (ulen > len)
3564                         ulen = len;
3565                     len -= ulen;
3566                     while (ulen--)
3567                         *d++ = *s++;
3568                 }
3569                 else {
3570                     if (!isALNUM(*s))
3571                         *d++ = '\\';
3572                     *d++ = *s++;
3573                     len--;
3574                 }
3575             }
3576             SvUTF8_on(TARG);
3577         }
3578         else {
3579             while (len--) {
3580                 if (!isALNUM(*s))
3581                     *d++ = '\\';
3582                 *d++ = *s++;
3583             }
3584         }
3585         *d = '\0';
3586         SvCUR_set(TARG, d - SvPVX_const(TARG));
3587         (void)SvPOK_only_UTF8(TARG);
3588     }
3589     else
3590         sv_setpvn(TARG, s, len);
3591     SETs(TARG);
3592     if (SvSMAGICAL(TARG))
3593         mg_set(TARG);
3594     RETURN;
3595 }
3596
3597 /* Arrays. */
3598
3599 PP(pp_aslice)
3600 {
3601     dVAR; dSP; dMARK; dORIGMARK;
3602     register AV* const av = (AV*)POPs;
3603     register const I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
3604
3605     if (SvTYPE(av) == SVt_PVAV) {
3606         const I32 arybase = PL_curcop->cop_arybase;
3607         if (lval && PL_op->op_private & OPpLVAL_INTRO) {
3608             register SV **svp;
3609             I32 max = -1;
3610             for (svp = MARK + 1; svp <= SP; svp++) {
3611                 const I32 elem = SvIVx(*svp);
3612                 if (elem > max)
3613                     max = elem;
3614             }
3615             if (max > AvMAX(av))
3616                 av_extend(av, max);
3617         }
3618         while (++MARK <= SP) {
3619             register SV **svp;
3620             I32 elem = SvIVx(*MARK);
3621
3622             if (elem > 0)
3623                 elem -= arybase;
3624             svp = av_fetch(av, elem, lval);
3625             if (lval) {
3626                 if (!svp || *svp == &PL_sv_undef)
3627                     DIE(aTHX_ PL_no_aelem, elem);
3628                 if (PL_op->op_private & OPpLVAL_INTRO)
3629                     save_aelem(av, elem, svp);
3630             }
3631             *MARK = svp ? *svp : &PL_sv_undef;
3632         }
3633     }
3634     if (GIMME != G_ARRAY) {
3635         MARK = ORIGMARK;
3636         *++MARK = SP > ORIGMARK ? *SP : &PL_sv_undef;
3637         SP = MARK;
3638     }
3639     RETURN;
3640 }
3641
3642 /* Associative arrays. */
3643
3644 PP(pp_each)
3645 {
3646     dVAR;
3647     dSP;
3648     HV * const hash = (HV*)POPs;
3649     HE *entry;
3650     const I32 gimme = GIMME_V;
3651
3652     PUTBACK;
3653     /* might clobber stack_sp */
3654     entry = hv_iternext(hash);
3655     SPAGAIN;
3656
3657     EXTEND(SP, 2);
3658     if (entry) {
3659         SV* const sv = hv_iterkeysv(entry);
3660         PUSHs(sv);      /* won't clobber stack_sp */
3661         if (gimme == G_ARRAY) {
3662             SV *val;
3663             PUTBACK;
3664             /* might clobber stack_sp */
3665             val = hv_iterval(hash, entry);
3666             SPAGAIN;
3667             PUSHs(val);
3668         }
3669     }
3670     else if (gimme == G_SCALAR)
3671         RETPUSHUNDEF;
3672
3673     RETURN;
3674 }
3675
3676 PP(pp_delete)
3677 {
3678     dVAR;
3679     dSP;
3680     const I32 gimme = GIMME_V;
3681     const I32 discard = (gimme == G_VOID) ? G_DISCARD : 0;
3682
3683     if (PL_op->op_private & OPpSLICE) {
3684         dMARK; dORIGMARK;
3685         HV * const hv = (HV*)POPs;
3686         const U32 hvtype = SvTYPE(hv);
3687         if (hvtype == SVt_PVHV) {                       /* hash element */
3688             while (++MARK <= SP) {
3689                 SV * const sv = hv_delete_ent(hv, *MARK, discard, 0);
3690                 *MARK = sv ? sv : &PL_sv_undef;
3691             }
3692         }
3693         else if (hvtype == SVt_PVAV) {                  /* array element */
3694             if (PL_op->op_flags & OPf_SPECIAL) {
3695                 while (++MARK <= SP) {
3696                     SV * const sv = av_delete((AV*)hv, SvIV(*MARK), discard);
3697                     *MARK = sv ? sv : &PL_sv_undef;
3698                 }
3699             }
3700         }
3701         else
3702             DIE(aTHX_ "Not a HASH reference");
3703         if (discard)
3704             SP = ORIGMARK;
3705         else if (gimme == G_SCALAR) {
3706             MARK = ORIGMARK;
3707             if (SP > MARK)
3708                 *++MARK = *SP;
3709             else
3710                 *++MARK = &PL_sv_undef;
3711             SP = MARK;
3712         }
3713     }
3714     else {
3715         SV *keysv = POPs;
3716         HV * const hv = (HV*)POPs;
3717         SV *sv;
3718         if (SvTYPE(hv) == SVt_PVHV)
3719             sv = hv_delete_ent(hv, keysv, discard, 0);
3720         else if (SvTYPE(hv) == SVt_PVAV) {
3721             if (PL_op->op_flags & OPf_SPECIAL)
3722                 sv = av_delete((AV*)hv, SvIV(keysv), discard);
3723             else
3724                 DIE(aTHX_ "panic: avhv_delete no longer supported");
3725         }
3726         else
3727             DIE(aTHX_ "Not a HASH reference");
3728         if (!sv)
3729             sv = &PL_sv_undef;
3730         if (!discard)
3731             PUSHs(sv);
3732     }
3733     RETURN;
3734 }
3735
3736 PP(pp_exists)
3737 {
3738     dVAR;
3739     dSP;
3740     SV *tmpsv;
3741     HV *hv;
3742
3743     if (PL_op->op_private & OPpEXISTS_SUB) {
3744         GV *gv;
3745         SV * const sv = POPs;
3746         CV * const cv = sv_2cv(sv, &hv, &gv, 0);
3747         if (cv)
3748             RETPUSHYES;
3749         if (gv && isGV(gv) && GvCV(gv) && !GvCVGEN(gv))
3750             RETPUSHYES;
3751         RETPUSHNO;
3752     }
3753     tmpsv = POPs;
3754     hv = (HV*)POPs;
3755     if (SvTYPE(hv) == SVt_PVHV) {
3756         if (hv_exists_ent(hv, tmpsv, 0))
3757             RETPUSHYES;
3758     }
3759     else if (SvTYPE(hv) == SVt_PVAV) {
3760         if (PL_op->op_flags & OPf_SPECIAL) {            /* array element */
3761             if (av_exists((AV*)hv, SvIV(tmpsv)))
3762                 RETPUSHYES;
3763         }
3764     }
3765     else {
3766         DIE(aTHX_ "Not a HASH reference");
3767     }
3768     RETPUSHNO;
3769 }
3770
3771 PP(pp_hslice)
3772 {
3773     dVAR; dSP; dMARK; dORIGMARK;
3774     register HV * const hv = (HV*)POPs;
3775     register const I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
3776     const bool localizing = PL_op->op_private & OPpLVAL_INTRO;
3777     bool other_magic = FALSE;
3778
3779     if (localizing) {
3780         MAGIC *mg;
3781         HV *stash;
3782
3783         other_magic = mg_find((SV*)hv, PERL_MAGIC_env) ||
3784             ((mg = mg_find((SV*)hv, PERL_MAGIC_tied))
3785              /* Try to preserve the existenceness of a tied hash
3786               * element by using EXISTS and DELETE if possible.
3787               * Fallback to FETCH and STORE otherwise */
3788              && (stash = SvSTASH(SvRV(SvTIED_obj((SV*)hv, mg))))
3789              && gv_fetchmethod_autoload(stash, "EXISTS", TRUE)
3790              && gv_fetchmethod_autoload(stash, "DELETE", TRUE));
3791     }
3792
3793     while (++MARK <= SP) {
3794         SV * const keysv = *MARK;
3795         SV **svp;
3796         HE *he;
3797         bool preeminent = FALSE;
3798
3799         if (localizing) {
3800             preeminent = SvRMAGICAL(hv) && !other_magic ? 1 :
3801                 hv_exists_ent(hv, keysv, 0);
3802         }
3803
3804         he = hv_fetch_ent(hv, keysv, lval, 0);
3805         svp = he ? &HeVAL(he) : 0;
3806
3807         if (lval) {
3808             if (!svp || *svp == &PL_sv_undef) {
3809                 DIE(aTHX_ PL_no_helem_sv, keysv);
3810             }
3811             if (localizing) {
3812                 if (preeminent)
3813                     save_helem(hv, keysv, svp);
3814                 else {
3815                     STRLEN keylen;
3816                     const char *key = SvPV_const(keysv, keylen);
3817                     SAVEDELETE(hv, savepvn(key,keylen), keylen);
3818                 }
3819             }
3820         }
3821         *MARK = svp ? *svp : &PL_sv_undef;
3822     }
3823     if (GIMME != G_ARRAY) {
3824         MARK = ORIGMARK;
3825         *++MARK = SP > ORIGMARK ? *SP : &PL_sv_undef;
3826         SP = MARK;
3827     }
3828     RETURN;
3829 }
3830
3831 /* List operators. */
3832
3833 PP(pp_list)
3834 {
3835     dVAR; dSP; dMARK;
3836     if (GIMME != G_ARRAY) {
3837         if (++MARK <= SP)
3838             *MARK = *SP;                /* unwanted list, return last item */
3839         else
3840             *MARK = &PL_sv_undef;
3841         SP = MARK;
3842     }
3843     RETURN;
3844 }
3845
3846 PP(pp_lslice)
3847 {
3848     dVAR;
3849     dSP;
3850     SV ** const lastrelem = PL_stack_sp;
3851     SV ** const lastlelem = PL_stack_base + POPMARK;
3852     SV ** const firstlelem = PL_stack_base + POPMARK + 1;
3853     register SV ** const firstrelem = lastlelem + 1;
3854     const I32 arybase = PL_curcop->cop_arybase;
3855     I32 is_something_there = PL_op->op_flags & OPf_MOD;
3856
3857     register const I32 max = lastrelem - lastlelem;
3858     register SV **lelem;
3859
3860     if (GIMME != G_ARRAY) {
3861         I32 ix = SvIVx(*lastlelem);
3862         if (ix < 0)
3863             ix += max;
3864         else
3865             ix -= arybase;
3866         if (ix < 0 || ix >= max)
3867             *firstlelem = &PL_sv_undef;
3868         else
3869             *firstlelem = firstrelem[ix];
3870         SP = firstlelem;
3871         RETURN;
3872     }
3873
3874     if (max == 0) {
3875         SP = firstlelem - 1;
3876         RETURN;
3877     }
3878
3879     for (lelem = firstlelem; lelem <= lastlelem; lelem++) {
3880         I32 ix = SvIVx(*lelem);
3881         if (ix < 0)
3882             ix += max;
3883         else
3884             ix -= arybase;
3885         if (ix < 0 || ix >= max)
3886             *lelem = &PL_sv_undef;
3887         else {
3888             is_something_there = TRUE;
3889             if (!(*lelem = firstrelem[ix]))
3890                 *lelem = &PL_sv_undef;
3891         }
3892     }
3893     if (is_something_there)
3894         SP = lastlelem;
3895     else
3896         SP = firstlelem - 1;
3897     RETURN;
3898 }
3899
3900 PP(pp_anonlist)
3901 {
3902     dVAR; dSP; dMARK; dORIGMARK;
3903     const I32 items = SP - MARK;
3904     SV * const av = sv_2mortal((SV*)av_make(items, MARK+1));
3905     SP = ORIGMARK;              /* av_make() might realloc stack_sp */
3906     XPUSHs(av);
3907     RETURN;
3908 }
3909
3910 PP(pp_anonhash)
3911 {
3912     dVAR; dSP; dMARK; dORIGMARK;
3913     HV* const hv = (HV*)sv_2mortal((SV*)newHV());
3914
3915     while (MARK < SP) {
3916         SV * const key = *++MARK;
3917         SV * const val = newSV(0);
3918         if (MARK < SP)
3919             sv_setsv(val, *++MARK);
3920         else if (ckWARN(WARN_MISC))
3921             Perl_warner(aTHX_ packWARN(WARN_MISC), "Odd number of elements in anonymous hash");
3922         (void)hv_store_ent(hv,key,val,0);
3923     }
3924     SP = ORIGMARK;
3925     XPUSHs((SV*)hv);
3926     RETURN;
3927 }
3928
3929 PP(pp_splice)
3930 {
3931     dVAR; dSP; dMARK; dORIGMARK;
3932     register AV *ary = (AV*)*++MARK;
3933     register SV **src;
3934     register SV **dst;
3935     register I32 i;
3936     register I32 offset;
3937     register I32 length;
3938     I32 newlen;
3939     I32 after;
3940     I32 diff;
3941     SV **tmparyval = NULL;
3942     const MAGIC * const mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied);
3943
3944     if (mg) {
3945         *MARK-- = SvTIED_obj((SV*)ary, mg);
3946         PUSHMARK(MARK);
3947         PUTBACK;
3948         ENTER;
3949         call_method("SPLICE",GIMME_V);
3950         LEAVE;
3951         SPAGAIN;
3952         RETURN;
3953     }
3954
3955     SP++;
3956
3957     if (++MARK < SP) {
3958         offset = i = SvIVx(*MARK);
3959         if (offset < 0)
3960             offset += AvFILLp(ary) + 1;
3961         else
3962             offset -= PL_curcop->cop_arybase;
3963         if (offset < 0)
3964             DIE(aTHX_ PL_no_aelem, i);
3965         if (++MARK < SP) {
3966             length = SvIVx(*MARK++);
3967             if (length < 0) {
3968                 length += AvFILLp(ary) - offset + 1;
3969                 if (length < 0)
3970                     length = 0;
3971             }
3972         }
3973         else
3974             length = AvMAX(ary) + 1;            /* close enough to infinity */
3975     }
3976     else {
3977         offset = 0;
3978         length = AvMAX(ary) + 1;
3979     }
3980     if (offset > AvFILLp(ary) + 1) {
3981         if (ckWARN(WARN_MISC))
3982             Perl_warner(aTHX_ packWARN(WARN_MISC), "splice() offset past end of array" );
3983         offset = AvFILLp(ary) + 1;
3984     }
3985     after = AvFILLp(ary) + 1 - (offset + length);
3986     if (after < 0) {                            /* not that much array */
3987         length += after;                        /* offset+length now in array */
3988         after = 0;
3989         if (!AvALLOC(ary))
3990             av_extend(ary, 0);
3991     }
3992
3993     /* At this point, MARK .. SP-1 is our new LIST */
3994
3995     newlen = SP - MARK;
3996     diff = newlen - length;
3997     if (newlen && !AvREAL(ary) && AvREIFY(ary))
3998         av_reify(ary);
3999
4000     /* make new elements SVs now: avoid problems if they're from the array */
4001     for (dst = MARK, i = newlen; i; i--) {
4002         SV * const h = *dst;
4003         *dst++ = newSVsv(h);
4004     }
4005
4006     if (diff < 0) {                             /* shrinking the area */
4007         if (newlen) {
4008             Newx(tmparyval, newlen, SV*);       /* so remember insertion */
4009             Copy(MARK, tmparyval, newlen, SV*);
4010         }
4011
4012         MARK = ORIGMARK + 1;
4013         if (GIMME == G_ARRAY) {                 /* copy return vals to stack */
4014             MEXTEND(MARK, length);
4015             Copy(AvARRAY(ary)+offset, MARK, length, SV*);
4016             if (AvREAL(ary)) {
4017                 EXTEND_MORTAL(length);
4018                 for (i = length, dst = MARK; i; i--) {
4019                     sv_2mortal(*dst);   /* free them eventualy */
4020                     dst++;
4021                 }
4022             }
4023             MARK += length - 1;
4024         }
4025         else {
4026             *MARK = AvARRAY(ary)[offset+length-1];
4027             if (AvREAL(ary)) {
4028                 sv_2mortal(*MARK);
4029                 for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
4030                     SvREFCNT_dec(*dst++);       /* free them now */
4031             }
4032         }
4033         AvFILLp(ary) += diff;
4034
4035         /* pull up or down? */
4036
4037         if (offset < after) {                   /* easier to pull up */
4038             if (offset) {                       /* esp. if nothing to pull */
4039                 src = &AvARRAY(ary)[offset-1];
4040                 dst = src - diff;               /* diff is negative */
4041                 for (i = offset; i > 0; i--)    /* can't trust Copy */
4042                     *dst-- = *src--;
4043             }
4044             dst = AvARRAY(ary);
4045             SvPV_set(ary, (char*)(AvARRAY(ary) - diff)); /* diff is negative */
4046             AvMAX(ary) += diff;
4047         }
4048         else {
4049             if (after) {                        /* anything to pull down? */
4050                 src = AvARRAY(ary) + offset + length;
4051                 dst = src + diff;               /* diff is negative */
4052                 Move(src, dst, after, SV*);
4053             }
4054             dst = &AvARRAY(ary)[AvFILLp(ary)+1];
4055                                                 /* avoid later double free */
4056         }
4057         i = -diff;
4058         while (i)
4059             dst[--i] = &PL_sv_undef;
4060         
4061         if (newlen) {
4062             Copy( tmparyval, AvARRAY(ary) + offset, newlen, SV* );
4063             Safefree(tmparyval);
4064         }
4065     }
4066     else {                                      /* no, expanding (or same) */
4067         if (length) {
4068             Newx(tmparyval, length, SV*);       /* so remember deletion */
4069             Copy(AvARRAY(ary)+offset, tmparyval, length, SV*);
4070         }
4071
4072         if (diff > 0) {                         /* expanding */
4073
4074             /* push up or down? */
4075
4076             if (offset < after && diff <= AvARRAY(ary) - AvALLOC(ary)) {
4077                 if (offset) {
4078                     src = AvARRAY(ary);
4079                     dst = src - diff;
4080                     Move(src, dst, offset, SV*);
4081                 }
4082                 SvPV_set(ary, (char*)(AvARRAY(ary) - diff));/* diff is positive */
4083                 AvMAX(ary) += diff;
4084                 AvFILLp(ary) += diff;
4085             }
4086             else {
4087                 if (AvFILLp(ary) + diff >= AvMAX(ary))  /* oh, well */
4088                     av_extend(ary, AvFILLp(ary) + diff);
4089                 AvFILLp(ary) += diff;
4090
4091                 if (after) {
4092                     dst = AvARRAY(ary) + AvFILLp(ary);
4093                     src = dst - diff;
4094                     for (i = after; i; i--) {
4095                         *dst-- = *src--;
4096                     }
4097                 }
4098             }
4099         }
4100
4101         if (newlen) {
4102             Copy( MARK, AvARRAY(ary) + offset, newlen, SV* );
4103         }
4104
4105         MARK = ORIGMARK + 1;
4106         if (GIMME == G_ARRAY) {                 /* copy return vals to stack */
4107             if (length) {
4108                 Copy(tmparyval, MARK, length, SV*);
4109                 if (AvREAL(ary)) {
4110                     EXTEND_MORTAL(length);
4111                     for (i = length, dst = MARK; i; i--) {
4112                         sv_2mortal(*dst);       /* free them eventualy */
4113                         dst++;
4114                     }
4115                 }
4116                 Safefree(tmparyval);
4117             }
4118             MARK += length - 1;
4119         }
4120         else if (length--) {
4121             *MARK = tmparyval[length];
4122             if (AvREAL(ary)) {
4123                 sv_2mortal(*MARK);
4124                 while (length-- > 0)
4125                     SvREFCNT_dec(tmparyval[length]);
4126             }
4127             Safefree(tmparyval);
4128         }
4129         else
4130             *MARK = &PL_sv_undef;
4131     }
4132     SP = MARK;
4133     RETURN;
4134 }
4135
4136 PP(pp_push)
4137 {
4138     dVAR; dSP; dMARK; dORIGMARK; dTARGET;
4139     register AV *ary = (AV*)*++MARK;
4140     const MAGIC * const mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied);
4141
4142     if (mg) {
4143         *MARK-- = SvTIED_obj((SV*)ary, mg);
4144         PUSHMARK(MARK);
4145         PUTBACK;
4146         ENTER;
4147         call_method("PUSH",G_SCALAR|G_DISCARD);
4148         LEAVE;
4149         SPAGAIN;
4150         SP = ORIGMARK;
4151         PUSHi( AvFILL(ary) + 1 );
4152     }
4153     else {
4154         for (++MARK; MARK <= SP; MARK++) {
4155             SV * const sv = newSV(0);
4156             if (*MARK)
4157                 sv_setsv(sv, *MARK);
4158             av_store(ary, AvFILLp(ary)+1, sv);
4159         }
4160         SP = ORIGMARK;
4161         PUSHi( AvFILLp(ary) + 1 );
4162     }
4163     RETURN;
4164 }
4165
4166 PP(pp_shift)
4167 {
4168     dVAR;
4169     dSP;
4170     AV * const av = (AV*)POPs;
4171     SV * const sv = PL_op->op_type == OP_SHIFT ? av_shift(av) : av_pop(av);
4172     EXTEND(SP, 1);
4173     assert (sv);
4174     if (AvREAL(av))
4175         (void)sv_2mortal(sv);
4176     PUSHs(sv);
4177     RETURN;
4178 }
4179
4180 PP(pp_unshift)
4181 {
4182     dVAR; dSP; dMARK; dORIGMARK; dTARGET;
4183     register AV *ary = (AV*)*++MARK;
4184     const MAGIC * const mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied);
4185
4186     if (mg) {
4187         *MARK-- = SvTIED_obj((SV*)ary, mg);
4188         PUSHMARK(MARK);
4189         PUTBACK;
4190         ENTER;
4191         call_method("UNSHIFT",G_SCALAR|G_DISCARD);
4192         LEAVE;
4193         SPAGAIN;
4194     }
4195     else {
4196         register I32 i = 0;
4197         av_unshift(ary, SP - MARK);
4198         while (MARK < SP) {
4199             SV * const sv = newSVsv(*++MARK);
4200             (void)av_store(ary, i++, sv);
4201         }
4202     }
4203     SP = ORIGMARK;
4204     PUSHi( AvFILL(ary) + 1 );
4205     RETURN;
4206 }
4207
4208 PP(pp_reverse)
4209 {
4210     dVAR; dSP; dMARK;
4211     SV ** const oldsp = SP;
4212
4213     if (GIMME == G_ARRAY) {
4214         MARK++;
4215         while (MARK < SP) {
4216             register SV * const tmp = *MARK;
4217             *MARK++ = *SP;
4218             *SP-- = tmp;
4219         }
4220         /* safe as long as stack cannot get extended in the above */
4221         SP = oldsp;
4222     }
4223     else {
4224         register char *up;
4225         register char *down;
4226         register I32 tmp;
4227         dTARGET;
4228         STRLEN len;
4229         I32 padoff_du;
4230
4231         SvUTF8_off(TARG);                               /* decontaminate */
4232         if (SP - MARK > 1)
4233             do_join(TARG, &PL_sv_no, MARK, SP);
4234         else
4235             sv_setsv(TARG, (SP > MARK)
4236                     ? *SP
4237                     : (padoff_du = find_rundefsvoffset(),
4238                         (padoff_du == NOT_IN_PAD || PAD_COMPNAME_FLAGS(padoff_du) & SVpad_OUR)
4239                         ? DEFSV : PAD_SVl(padoff_du)));
4240         up = SvPV_force(TARG, len);
4241         if (len > 1) {
4242             if (DO_UTF8(TARG)) {        /* first reverse each character */
4243                 U8* s = (U8*)SvPVX(TARG);
4244                 const U8* send = (U8*)(s + len);
4245                 while (s < send) {
4246                     if (UTF8_IS_INVARIANT(*s)) {
4247                         s++;
4248                         continue;
4249                     }
4250                     else {
4251                         if (!utf8_to_uvchr(s, 0))
4252                             break;
4253                         up = (char*)s;
4254                         s += UTF8SKIP(s);
4255                         down = (char*)(s - 1);
4256                         /* reverse this character */
4257                         while (down > up) {
4258                             tmp = *up;
4259                             *up++ = *down;
4260                             *down-- = (char)tmp;
4261                         }
4262                     }
4263                 }
4264                 up = SvPVX(TARG);
4265             }
4266             down = SvPVX(TARG) + len - 1;
4267             while (down > up) {
4268                 tmp = *up;
4269                 *up++ = *down;
4270                 *down-- = (char)tmp;
4271             }
4272             (void)SvPOK_only_UTF8(TARG);
4273         }
4274         SP = MARK + 1;
4275         SETTARG;
4276     }
4277     RETURN;
4278 }
4279
4280 PP(pp_split)
4281 {
4282     dVAR; dSP; dTARG;
4283     AV *ary;
4284     register IV limit = POPi;                   /* note, negative is forever */
4285     SV * const sv = POPs;
4286     STRLEN len;
4287     register const char *s = SvPV_const(sv, len);
4288     const bool do_utf8 = DO_UTF8(sv);
4289     const char *strend = s + len;
4290     register PMOP *pm;
4291     register REGEXP *rx;
4292     register SV *dstr;
4293     register const char *m;
4294     I32 iters = 0;
4295     const STRLEN slen = do_utf8 ? utf8_length((U8*)s, (U8*)strend) : (strend - s);
4296     I32 maxiters = slen + 10;
4297     const char *orig;
4298     const I32 origlimit = limit;
4299     I32 realarray = 0;
4300     I32 base;
4301     const I32 gimme = GIMME_V;
4302     const I32 oldsave = PL_savestack_ix;
4303     I32 make_mortal = 1;
4304     bool multiline = 0;
4305     MAGIC *mg = (MAGIC *) NULL;
4306
4307 #ifdef DEBUGGING
4308     Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
4309 #else
4310     pm = (PMOP*)POPs;
4311 #endif
4312     if (!pm || !s)
4313         DIE(aTHX_ "panic: pp_split");
4314     rx = PM_GETRE(pm);
4315
4316     TAINT_IF((pm->op_pmflags & PMf_LOCALE) &&
4317              (pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE)));
4318
4319     RX_MATCH_UTF8_set(rx, do_utf8);
4320
4321     if (pm->op_pmreplroot) {
4322 #ifdef USE_ITHREADS
4323         ary = GvAVn((GV*)PAD_SVl(INT2PTR(PADOFFSET, pm->op_pmreplroot)));
4324 #else
4325         ary = GvAVn((GV*)pm->op_pmreplroot);
4326 #endif
4327     }
4328     else if (gimme != G_ARRAY)
4329         ary = GvAVn(PL_defgv);
4330     else
4331         ary = NULL;
4332     if (ary && (gimme != G_ARRAY || (pm->op_pmflags & PMf_ONCE))) {
4333         realarray = 1;
4334         PUTBACK;
4335         av_extend(ary,0);
4336         av_clear(ary);
4337         SPAGAIN;
4338         if ((mg = SvTIED_mg((SV*)ary, PERL_MAGIC_tied))) {
4339             PUSHMARK(SP);
4340             XPUSHs(SvTIED_obj((SV*)ary, mg));
4341         }
4342         else {
4343             if (!AvREAL(ary)) {
4344                 I32 i;
4345                 AvREAL_on(ary);
4346                 AvREIFY_off(ary);
4347                 for (i = AvFILLp(ary); i >= 0; i--)
4348                     AvARRAY(ary)[i] = &PL_sv_undef;     /* don't free mere refs */
4349             }
4350             /* temporarily switch stacks */
4351             SAVESWITCHSTACK(PL_curstack, ary);
4352             make_mortal = 0;
4353         }
4354     }
4355     base = SP - PL_stack_base;
4356     orig = s;
4357     if (pm->op_pmflags & PMf_SKIPWHITE) {
4358         if (pm->op_pmflags & PMf_LOCALE) {
4359             while (isSPACE_LC(*s))
4360                 s++;
4361         }
4362         else {
4363             while (isSPACE(*s))
4364                 s++;
4365         }
4366     }
4367     if (pm->op_pmflags & PMf_MULTILINE) {
4368         multiline = 1;
4369     }
4370
4371     if (!limit)
4372         limit = maxiters + 2;
4373     if (pm->op_pmflags & PMf_WHITE) {
4374         while (--limit) {
4375             m = s;
4376             while (m < strend &&
4377                    !((pm->op_pmflags & PMf_LOCALE)
4378                      ? isSPACE_LC(*m) : isSPACE(*m)))
4379                 ++m;
4380             if (m >= strend)
4381                 break;
4382
4383             dstr = newSVpvn(s, m-s);
4384             if (make_mortal)
4385                 sv_2mortal(dstr);
4386             if (do_utf8)
4387                 (void)SvUTF8_on(dstr);
4388             XPUSHs(dstr);
4389
4390             s = m + 1;
4391             while (s < strend &&
4392                    ((pm->op_pmflags & PMf_LOCALE)
4393                     ? isSPACE_LC(*s) : isSPACE(*s)))
4394                 ++s;
4395         }
4396     }
4397     else if (rx->precomp[0] == '^' && rx->precomp[1] == '\0') {
4398         while (--limit) {
4399             for (m = s; m < strend && *m != '\n'; m++)
4400                 ;
4401             m++;
4402             if (m >= strend)
4403                 break;
4404             dstr = newSVpvn(s, m-s);
4405             if (make_mortal)
4406                 sv_2mortal(dstr);
4407             if (do_utf8)
4408                 (void)SvUTF8_on(dstr);
4409             XPUSHs(dstr);
4410             s = m;
4411         }
4412     }
4413     else if (do_utf8 == ((rx->reganch & ROPT_UTF8) != 0) &&
4414              (rx->reganch & RE_USE_INTUIT) && !rx->nparens
4415              && (rx->reganch & ROPT_CHECK_ALL)
4416              && !(rx->reganch & ROPT_ANCH)) {
4417         const int tail = (rx->reganch & RE_INTUIT_TAIL);
4418         SV * const csv = CALLREG_INTUIT_STRING(aTHX_ rx);
4419
4420         len = rx->minlen;
4421         if (len == 1 && !(rx->reganch & ROPT_UTF8) && !tail) {
4422             const char c = *SvPV_nolen_const(csv);
4423             while (--limit) {
4424                 for (m = s; m < strend && *m != c; m++)
4425                     ;
4426                 if (m >= strend)
4427                     break;
4428                 dstr = newSVpvn(s, m-s);
4429                 if (make_mortal)
4430                     sv_2mortal(dstr);
4431                 if (do_utf8)
4432                     (void)SvUTF8_on(dstr);
4433                 XPUSHs(dstr);
4434                 /* The rx->minlen is in characters but we want to step
4435                  * s ahead by bytes. */
4436                 if (do_utf8)
4437                     s = (char*)utf8_hop((U8*)m, len);
4438                 else
4439                     s = m + len; /* Fake \n at the end */
4440             }
4441         }
4442         else {
4443             while (s < strend && --limit &&
4444               (m = fbm_instr((unsigned char*)s, (unsigned char*)strend,
4445                              csv, multiline ? FBMrf_MULTILINE : 0)) )
4446             {
4447                 dstr = newSVpvn(s, m-s);
4448                 if (make_mortal)
4449                     sv_2mortal(dstr);
4450                 if (do_utf8)
4451                     (void)SvUTF8_on(dstr);
4452                 XPUSHs(dstr);
4453                 /* The rx->minlen is in characters but we want to step
4454                  * s ahead by bytes. */
4455                 if (do_utf8)
4456                     s = (char*)utf8_hop((U8*)m, len);
4457                 else
4458                     s = m + len; /* Fake \n at the end */
4459             }
4460         }
4461     }
4462     else {
4463         maxiters += slen * rx->nparens;
4464         while (s < strend && --limit)
4465         {
4466             I32 rex_return;
4467             PUTBACK;
4468             rex_return = CALLREGEXEC(aTHX_ rx, (char*)s, (char*)strend, (char*)orig, 1 ,
4469                             sv, NULL, 0);
4470             SPAGAIN;
4471             if (rex_return == 0)
4472                 break;
4473             TAINT_IF(RX_MATCH_TAINTED(rx));
4474             if (RX_MATCH_COPIED(rx) && rx->subbeg != orig) {
4475                 m = s;
4476                 s = orig;
4477                 orig = rx->subbeg;
4478                 s = orig + (m - s);
4479                 strend = s + (strend - m);
4480             }
4481             m = rx->startp[0] + orig;
4482             dstr = newSVpvn(s, m-s);
4483             if (make_mortal)
4484                 sv_2mortal(dstr);
4485             if (do_utf8)
4486                 (void)SvUTF8_on(dstr);
4487             XPUSHs(dstr);
4488             if (rx->nparens) {
4489                 I32 i;
4490                 for (i = 1; i <= (I32)rx->nparens; i++) {
4491                     s = rx->startp[i] + orig;
4492                     m = rx->endp[i] + orig;
4493
4494                     /* japhy (07/27/01) -- the (m && s) test doesn't catch
4495                        parens that didn't match -- they should be set to
4496                        undef, not the empty string */
4497                     if (m >= orig && s >= orig) {
4498                         dstr = newSVpvn(s, m-s);
4499                     }
4500                     else
4501                         dstr = &PL_sv_undef;  /* undef, not "" */
4502                     if (make_mortal)
4503                         sv_2mortal(dstr);
4504                     if (do_utf8)
4505                         (void)SvUTF8_on(dstr);
4506                     XPUSHs(dstr);
4507                 }
4508             }
4509             s = rx->endp[0] + orig;
4510         }
4511     }
4512
4513     iters = (SP - PL_stack_base) - base;
4514     if (iters > maxiters)
4515         DIE(aTHX_ "Split loop");
4516
4517     /* keep field after final delim? */
4518     if (s < strend || (iters && origlimit)) {
4519         const STRLEN l = strend - s;
4520         dstr = newSVpvn(s, l);
4521         if (make_mortal)
4522             sv_2mortal(dstr);
4523         if (do_utf8)
4524             (void)SvUTF8_on(dstr);
4525         XPUSHs(dstr);
4526         iters++;
4527     }
4528     else if (!origlimit) {
4529         while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0)) {
4530             if (TOPs && !make_mortal)
4531                 sv_2mortal(TOPs);
4532             iters--;
4533             *SP-- = &PL_sv_undef;
4534         }
4535     }
4536
4537     PUTBACK;
4538     LEAVE_SCOPE(oldsave); /* may undo an earlier SWITCHSTACK */
4539     SPAGAIN;
4540     if (realarray) {
4541         if (!mg) {
4542             if (SvSMAGICAL(ary)) {
4543                 PUTBACK;
4544                 mg_set((SV*)ary);
4545                 SPAGAIN;
4546             }
4547             if (gimme == G_ARRAY) {
4548                 EXTEND(SP, iters);
4549                 Copy(AvARRAY(ary), SP + 1, iters, SV*);
4550                 SP += iters;
4551                 RETURN;
4552             }
4553         }
4554         else {
4555             PUTBACK;
4556             ENTER;
4557             call_method("PUSH",G_SCALAR|G_DISCARD);
4558             LEAVE;
4559             SPAGAIN;
4560             if (gimme == G_ARRAY) {
4561                 I32 i;
4562                 /* EXTEND should not be needed - we just popped them */
4563                 EXTEND(SP, iters);
4564                 for (i=0; i < iters; i++) {
4565                     SV **svp = av_fetch(ary, i, FALSE);
4566                     PUSHs((svp) ? *svp : &PL_sv_undef);
4567                 }
4568                 RETURN;
4569             }
4570         }
4571     }
4572     else {
4573         if (gimme == G_ARRAY)
4574             RETURN;
4575     }
4576
4577     GETTARGET;
4578     PUSHi(iters);
4579     RETURN;
4580 }
4581
4582 PP(pp_lock)
4583 {
4584     dVAR;
4585     dSP;
4586     dTOPss;
4587     SV *retsv = sv;
4588     SvLOCK(sv);
4589     if (SvTYPE(retsv) == SVt_PVAV || SvTYPE(retsv) == SVt_PVHV
4590         || SvTYPE(retsv) == SVt_PVCV) {
4591         retsv = refto(retsv);
4592     }
4593     SETs(retsv);
4594     RETURN;
4595 }
4596
4597
4598 PP(unimplemented_op)
4599 {
4600     dVAR;
4601     DIE(aTHX_ "panic: unimplemented op %s (#%d) called", OP_NAME(PL_op),
4602         PL_op->op_type);
4603 }
4604
4605 /*
4606  * Local variables:
4607  * c-indentation-style: bsd
4608  * c-basic-offset: 4
4609  * indent-tabs-mode: t
4610  * End:
4611  *
4612  * ex: set ts=8 sts=4 sw=4 noet:
4613  */