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