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