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