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