This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regen/embed.pl: Don't: #define FOO FOO
[perl5.git] / universal.c
... / ...
CommitLineData
1/* universal.c
2 *
3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 * 2005, 2006, 2007, 2008 by Larry Wall and others
5 *
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Artistic License, as specified in the README file.
8 *
9 */
10
11/*
12 * '"The roots of those mountains must be roots indeed; there must be
13 * great secrets buried there which have not been discovered since the
14 * beginning."' --Gandalf, relating Gollum's history
15 *
16 * [p.54 of _The Lord of the Rings_, I/ii: "The Shadow of the Past"]
17 */
18
19/* This file contains the code that implements the functions in Perl's
20 * UNIVERSAL package, such as UNIVERSAL->can().
21 *
22 * It is also used to store XS functions that need to be present in
23 * miniperl for a lack of a better place to put them. It might be
24 * clever to move them to separate XS files which would then be pulled
25 * in by some to-be-written build process.
26 */
27
28#include "EXTERN.h"
29#define PERL_IN_UNIVERSAL_C
30#include "perl.h"
31
32#if defined(USE_PERLIO)
33#include "perliol.h" /* For the PERLIO_F_XXX */
34#endif
35
36/*
37 * Contributed by Graham Barr <Graham.Barr@tiuk.ti.com>
38 * The main guts of traverse_isa was actually copied from gv_fetchmeth
39 */
40
41STATIC bool
42S_isa_lookup(pTHX_ HV *stash, const char * const name, STRLEN len, U32 flags)
43{
44 const struct mro_meta *const meta = HvMROMETA(stash);
45 HV *isa = meta->isa;
46 const HV *our_stash;
47
48 PERL_ARGS_ASSERT_ISA_LOOKUP;
49
50 if (!isa) {
51 (void)mro_get_linear_isa(stash);
52 isa = meta->isa;
53 }
54
55 if (hv_common(isa, NULL, name, len, ( flags & SVf_UTF8 ? HVhek_UTF8 : 0),
56 HV_FETCH_ISEXISTS, NULL, 0)) {
57 /* Direct name lookup worked. */
58 return TRUE;
59 }
60
61 /* A stash/class can go by many names (ie. User == main::User), so
62 we use the HvENAME in the stash itself, which is canonical, falling
63 back to HvNAME if necessary. */
64 our_stash = gv_stashpvn(name, len, flags);
65
66 if (our_stash) {
67 HEK *canon_name = HvENAME_HEK(our_stash);
68 if (!canon_name) canon_name = HvNAME_HEK(our_stash);
69 assert(canon_name);
70 if (hv_common(isa, NULL, HEK_KEY(canon_name), HEK_LEN(canon_name),
71 HEK_FLAGS(canon_name),
72 HV_FETCH_ISEXISTS, NULL, HEK_HASH(canon_name))) {
73 return TRUE;
74 }
75 }
76
77 return FALSE;
78}
79
80/*
81=head1 SV Manipulation Functions
82
83=for apidoc sv_derived_from_pvn
84
85Returns a boolean indicating whether the SV is derived from the specified class
86I<at the C level>. To check derivation at the Perl level, call C<isa()> as a
87normal Perl method.
88
89Currently, the only significant value for C<flags> is SVf_UTF8.
90
91=cut
92
93=for apidoc sv_derived_from_sv
94
95Exactly like L</sv_derived_from_pvn>, but takes the name string in the form
96of an SV instead of a string/length pair.
97
98=cut
99
100*/
101
102bool
103Perl_sv_derived_from_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
104{
105 char *namepv;
106 STRLEN namelen;
107 PERL_ARGS_ASSERT_SV_DERIVED_FROM_SV;
108 namepv = SvPV(namesv, namelen);
109 if (SvUTF8(namesv))
110 flags |= SVf_UTF8;
111 return sv_derived_from_pvn(sv, namepv, namelen, flags);
112}
113
114/*
115=for apidoc sv_derived_from
116
117Exactly like L</sv_derived_from_pv>, but doesn't take a C<flags> parameter.
118
119=cut
120*/
121
122bool
123Perl_sv_derived_from(pTHX_ SV *sv, const char *const name)
124{
125 PERL_ARGS_ASSERT_SV_DERIVED_FROM;
126 return sv_derived_from_pvn(sv, name, strlen(name), 0);
127}
128
129/*
130=for apidoc sv_derived_from_pv
131
132Exactly like L</sv_derived_from_pvn>, but takes a nul-terminated string
133instead of a string/length pair.
134
135=cut
136*/
137
138
139bool
140Perl_sv_derived_from_pv(pTHX_ SV *sv, const char *const name, U32 flags)
141{
142 PERL_ARGS_ASSERT_SV_DERIVED_FROM_PV;
143 return sv_derived_from_pvn(sv, name, strlen(name), flags);
144}
145
146bool
147Perl_sv_derived_from_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len, U32 flags)
148{
149 HV *stash;
150
151 PERL_ARGS_ASSERT_SV_DERIVED_FROM_PVN;
152
153 SvGETMAGIC(sv);
154
155 if (SvROK(sv)) {
156 const char *type;
157 sv = SvRV(sv);
158 type = sv_reftype(sv,0);
159 if (type && strEQ(type,name))
160 return TRUE;
161 if (!SvOBJECT(sv))
162 return FALSE;
163 stash = SvSTASH(sv);
164 }
165 else {
166 stash = gv_stashsv(sv, 0);
167 }
168
169 if (stash && isa_lookup(stash, name, len, flags))
170 return TRUE;
171
172 stash = gv_stashpvs("UNIVERSAL", 0);
173 return stash && isa_lookup(stash, name, len, flags);
174}
175
176/*
177=for apidoc sv_does_sv
178
179Returns a boolean indicating whether the SV performs a specific, named role.
180The SV can be a Perl object or the name of a Perl class.
181
182=cut
183*/
184
185#include "XSUB.h"
186
187bool
188Perl_sv_does_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
189{
190 SV *classname;
191 bool does_it;
192 SV *methodname;
193 dSP;
194
195 PERL_ARGS_ASSERT_SV_DOES_SV;
196 PERL_UNUSED_ARG(flags);
197
198 ENTER;
199 SAVETMPS;
200
201 SvGETMAGIC(sv);
202
203 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv)))) {
204 LEAVE;
205 return FALSE;
206 }
207
208 if (SvROK(sv) && SvOBJECT(SvRV(sv))) {
209 classname = sv_ref(NULL,SvRV(sv),TRUE);
210 } else {
211 classname = sv;
212 }
213
214 if (sv_eq(classname, namesv)) {
215 LEAVE;
216 return TRUE;
217 }
218
219 PUSHMARK(SP);
220 EXTEND(SP, 2);
221 PUSHs(sv);
222 PUSHs(namesv);
223 PUTBACK;
224
225 methodname = newSVpvs_flags("isa", SVs_TEMP);
226 /* ugly hack: use the SvSCREAM flag so S_method_common
227 * can figure out we're calling DOES() and not isa(),
228 * and report eventual errors correctly. --rgs */
229 SvSCREAM_on(methodname);
230 call_sv(methodname, G_SCALAR | G_METHOD);
231 SPAGAIN;
232
233 does_it = SvTRUE( TOPs );
234 FREETMPS;
235 LEAVE;
236
237 return does_it;
238}
239
240/*
241=for apidoc sv_does
242
243Like L</sv_does_pv>, but doesn't take a C<flags> parameter.
244
245=cut
246*/
247
248bool
249Perl_sv_does(pTHX_ SV *sv, const char *const name)
250{
251 PERL_ARGS_ASSERT_SV_DOES;
252 return sv_does_sv(sv, newSVpvn_flags(name, strlen(name), SVs_TEMP), 0);
253}
254
255/*
256=for apidoc sv_does_pv
257
258Like L</sv_does_sv>, but takes a nul-terminated string instead of an SV.
259
260=cut
261*/
262
263
264bool
265Perl_sv_does_pv(pTHX_ SV *sv, const char *const name, U32 flags)
266{
267 PERL_ARGS_ASSERT_SV_DOES_PV;
268 return sv_does_sv(sv, newSVpvn_flags(name, strlen(name), SVs_TEMP | flags), flags);
269}
270
271/*
272=for apidoc sv_does_pvn
273
274Like L</sv_does_sv>, but takes a string/length pair instead of an SV.
275
276=cut
277*/
278
279bool
280Perl_sv_does_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len, U32 flags)
281{
282 PERL_ARGS_ASSERT_SV_DOES_PVN;
283
284 return sv_does_sv(sv, newSVpvn_flags(name, len, flags | SVs_TEMP), flags);
285}
286
287/*
288=for apidoc croak_xs_usage
289
290A specialised variant of C<croak()> for emitting the usage message for xsubs
291
292 croak_xs_usage(cv, "eee_yow");
293
294works out the package name and subroutine name from C<cv>, and then calls
295C<croak()>. Hence if C<cv> is C<&ouch::awk>, it would call C<croak> as:
296
297 Perl_croak(aTHX_ "Usage: %"SVf"::%"SVf"(%s)", "ouch" "awk",
298 "eee_yow");
299
300=cut
301*/
302
303void
304Perl_croak_xs_usage(const CV *const cv, const char *const params)
305{
306 /* Avoid CvGV as it requires aTHX. */
307 const GV *gv = CvNAMED(cv) ? NULL : cv->sv_any->xcv_gv_u.xcv_gv;
308
309 PERL_ARGS_ASSERT_CROAK_XS_USAGE;
310
311 if (gv) got_gv: {
312 const HV *const stash = GvSTASH(gv);
313
314 if (HvNAME_get(stash))
315 /* diag_listed_as: SKIPME */
316 Perl_croak_nocontext("Usage: %"HEKf"::%"HEKf"(%s)",
317 HEKfARG(HvNAME_HEK(stash)),
318 HEKfARG(GvNAME_HEK(gv)),
319 params);
320 else
321 /* diag_listed_as: SKIPME */
322 Perl_croak_nocontext("Usage: %"HEKf"(%s)",
323 HEKfARG(GvNAME_HEK(gv)), params);
324 } else {
325 dTHX;
326 if ((gv = CvGV(cv))) goto got_gv;
327
328 /* Pants. I don't think that it should be possible to get here. */
329 /* diag_listed_as: SKIPME */
330 Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
331 }
332}
333
334XS(XS_UNIVERSAL_isa); /* prototype to pass -Wmissing-prototypes */
335XS(XS_UNIVERSAL_isa)
336{
337 dXSARGS;
338
339 if (items != 2)
340 croak_xs_usage(cv, "reference, kind");
341 else {
342 SV * const sv = ST(0);
343
344 SvGETMAGIC(sv);
345
346 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))))
347 XSRETURN_UNDEF;
348
349 ST(0) = boolSV(sv_derived_from_sv(sv, ST(1), 0));
350 XSRETURN(1);
351 }
352}
353
354XS(XS_UNIVERSAL_can); /* prototype to pass -Wmissing-prototypes */
355XS(XS_UNIVERSAL_can)
356{
357 dXSARGS;
358 SV *sv;
359 SV *rv;
360 HV *pkg = NULL;
361 GV *iogv;
362
363 if (items != 2)
364 croak_xs_usage(cv, "object-ref, method");
365
366 sv = ST(0);
367
368 SvGETMAGIC(sv);
369
370 /* Reject undef and empty string. Note that the string form takes
371 precedence here over the numeric form, as (!1)->foo treats the
372 invocant as the empty string, though it is a dualvar. */
373 if (!SvOK(sv) || (SvPOK(sv) && !SvCUR(sv)))
374 XSRETURN_UNDEF;
375
376 rv = &PL_sv_undef;
377
378 if (SvROK(sv)) {
379 sv = MUTABLE_SV(SvRV(sv));
380 if (SvOBJECT(sv))
381 pkg = SvSTASH(sv);
382 else if (isGV_with_GP(sv) && GvIO(sv))
383 pkg = SvSTASH(GvIO(sv));
384 }
385 else if (isGV_with_GP(sv) && GvIO(sv))
386 pkg = SvSTASH(GvIO(sv));
387 else if ((iogv = gv_fetchsv_nomg(sv, 0, SVt_PVIO)) && GvIO(iogv))
388 pkg = SvSTASH(GvIO(iogv));
389 else {
390 pkg = gv_stashsv(sv, 0);
391 if (!pkg)
392 pkg = gv_stashpvs("UNIVERSAL", 0);
393 }
394
395 if (pkg) {
396 GV * const gv = gv_fetchmethod_sv_flags(pkg, ST(1), 0);
397 if (gv && isGV(gv))
398 rv = sv_2mortal(newRV(MUTABLE_SV(GvCV(gv))));
399 }
400
401 ST(0) = rv;
402 XSRETURN(1);
403}
404
405XS(XS_UNIVERSAL_DOES); /* prototype to pass -Wmissing-prototypes */
406XS(XS_UNIVERSAL_DOES)
407{
408 dXSARGS;
409 PERL_UNUSED_ARG(cv);
410
411 if (items != 2)
412 Perl_croak(aTHX_ "Usage: invocant->DOES(kind)");
413 else {
414 SV * const sv = ST(0);
415 if (sv_does_sv( sv, ST(1), 0 ))
416 XSRETURN_YES;
417
418 XSRETURN_NO;
419 }
420}
421
422XS(XS_utf8_is_utf8); /* prototype to pass -Wmissing-prototypes */
423XS(XS_utf8_is_utf8)
424{
425 dXSARGS;
426 if (items != 1)
427 croak_xs_usage(cv, "sv");
428 else {
429 SV * const sv = ST(0);
430 SvGETMAGIC(sv);
431 if (SvUTF8(sv))
432 XSRETURN_YES;
433 else
434 XSRETURN_NO;
435 }
436 XSRETURN_EMPTY;
437}
438
439XS(XS_utf8_valid); /* prototype to pass -Wmissing-prototypes */
440XS(XS_utf8_valid)
441{
442 dXSARGS;
443 if (items != 1)
444 croak_xs_usage(cv, "sv");
445 else {
446 SV * const sv = ST(0);
447 STRLEN len;
448 const char * const s = SvPV_const(sv,len);
449 if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len))
450 XSRETURN_YES;
451 else
452 XSRETURN_NO;
453 }
454 XSRETURN_EMPTY;
455}
456
457XS(XS_utf8_encode); /* prototype to pass -Wmissing-prototypes */
458XS(XS_utf8_encode)
459{
460 dXSARGS;
461 if (items != 1)
462 croak_xs_usage(cv, "sv");
463 sv_utf8_encode(ST(0));
464 SvSETMAGIC(ST(0));
465 XSRETURN_EMPTY;
466}
467
468XS(XS_utf8_decode); /* prototype to pass -Wmissing-prototypes */
469XS(XS_utf8_decode)
470{
471 dXSARGS;
472 if (items != 1)
473 croak_xs_usage(cv, "sv");
474 else {
475 SV * const sv = ST(0);
476 bool RETVAL;
477 SvPV_force_nolen(sv);
478 RETVAL = sv_utf8_decode(sv);
479 SvSETMAGIC(sv);
480 ST(0) = boolSV(RETVAL);
481 }
482 XSRETURN(1);
483}
484
485XS(XS_utf8_upgrade); /* prototype to pass -Wmissing-prototypes */
486XS(XS_utf8_upgrade)
487{
488 dXSARGS;
489 if (items != 1)
490 croak_xs_usage(cv, "sv");
491 else {
492 SV * const sv = ST(0);
493 STRLEN RETVAL;
494 dXSTARG;
495
496 RETVAL = sv_utf8_upgrade(sv);
497 XSprePUSH; PUSHi((IV)RETVAL);
498 }
499 XSRETURN(1);
500}
501
502XS(XS_utf8_downgrade); /* prototype to pass -Wmissing-prototypes */
503XS(XS_utf8_downgrade)
504{
505 dXSARGS;
506 if (items < 1 || items > 2)
507 croak_xs_usage(cv, "sv, failok=0");
508 else {
509 SV * const sv = ST(0);
510 const bool failok = (items < 2) ? 0 : SvTRUE(ST(1)) ? 1 : 0;
511 const bool RETVAL = sv_utf8_downgrade(sv, failok);
512
513 ST(0) = boolSV(RETVAL);
514 }
515 XSRETURN(1);
516}
517
518XS(XS_utf8_native_to_unicode); /* prototype to pass -Wmissing-prototypes */
519XS(XS_utf8_native_to_unicode)
520{
521 dXSARGS;
522 const UV uv = SvUV(ST(0));
523
524 if (items > 1)
525 croak_xs_usage(cv, "sv");
526
527 ST(0) = sv_2mortal(newSVuv(NATIVE_TO_UNI(uv)));
528 XSRETURN(1);
529}
530
531XS(XS_utf8_unicode_to_native); /* prototype to pass -Wmissing-prototypes */
532XS(XS_utf8_unicode_to_native)
533{
534 dXSARGS;
535 const UV uv = SvUV(ST(0));
536
537 if (items > 1)
538 croak_xs_usage(cv, "sv");
539
540 ST(0) = sv_2mortal(newSVuv(UNI_TO_NATIVE(uv)));
541 XSRETURN(1);
542}
543
544XS(XS_Internals_SvREADONLY); /* prototype to pass -Wmissing-prototypes */
545XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
546{
547 dXSARGS;
548 SV * const svz = ST(0);
549 SV * sv;
550 PERL_UNUSED_ARG(cv);
551
552 /* [perl #77776] - called as &foo() not foo() */
553 if (!SvROK(svz))
554 croak_xs_usage(cv, "SCALAR[, ON]");
555
556 sv = SvRV(svz);
557
558 if (items == 1) {
559 if (SvREADONLY(sv))
560 XSRETURN_YES;
561 else
562 XSRETURN_NO;
563 }
564 else if (items == 2) {
565 if (SvTRUE(ST(1))) {
566 SvFLAGS(sv) |= SVf_READONLY;
567 XSRETURN_YES;
568 }
569 else {
570 /* I hope you really know what you are doing. */
571 SvFLAGS(sv) &=~ SVf_READONLY;
572 XSRETURN_NO;
573 }
574 }
575 XSRETURN_UNDEF; /* Can't happen. */
576}
577
578XS(XS_constant__make_const); /* prototype to pass -Wmissing-prototypes */
579XS(XS_constant__make_const) /* This is dangerous stuff. */
580{
581 dXSARGS;
582 SV * const svz = ST(0);
583 SV * sv;
584 PERL_UNUSED_ARG(cv);
585
586 /* [perl #77776] - called as &foo() not foo() */
587 if (!SvROK(svz) || items != 1)
588 croak_xs_usage(cv, "SCALAR");
589
590 sv = SvRV(svz);
591
592 SvREADONLY_on(sv);
593 if (SvTYPE(sv) == SVt_PVAV && AvFILLp(sv) != -1) {
594 /* for constant.pm; nobody else should be calling this
595 on arrays anyway. */
596 SV **svp;
597 for (svp = AvARRAY(sv) + AvFILLp(sv)
598 ; svp >= AvARRAY(sv)
599 ; --svp)
600 if (*svp) SvPADTMP_on(*svp);
601 }
602 XSRETURN(0);
603}
604
605XS(XS_Internals_SvREFCNT); /* prototype to pass -Wmissing-prototypes */
606XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
607{
608 dXSARGS;
609 SV * const svz = ST(0);
610 SV * sv;
611 U32 refcnt;
612 PERL_UNUSED_ARG(cv);
613
614 /* [perl #77776] - called as &foo() not foo() */
615 if ((items != 1 && items != 2) || !SvROK(svz))
616 croak_xs_usage(cv, "SCALAR[, REFCOUNT]");
617
618 sv = SvRV(svz);
619
620 /* I hope you really know what you are doing. */
621 /* idea is for SvREFCNT(sv) to be accessed only once */
622 refcnt = items == 2 ?
623 /* we free one ref on exit */
624 (SvREFCNT(sv) = SvUV(ST(1)) + 1)
625 : SvREFCNT(sv);
626 XSRETURN_UV(refcnt - 1); /* Minus the ref created for us. */
627
628}
629
630XS(XS_Internals_hv_clear_placehold); /* prototype to pass -Wmissing-prototypes */
631XS(XS_Internals_hv_clear_placehold)
632{
633 dXSARGS;
634
635 if (items != 1 || !SvROK(ST(0)))
636 croak_xs_usage(cv, "hv");
637 else {
638 HV * const hv = MUTABLE_HV(SvRV(ST(0)));
639 hv_clear_placeholders(hv);
640 XSRETURN(0);
641 }
642}
643
644XS(XS_PerlIO_get_layers); /* prototype to pass -Wmissing-prototypes */
645XS(XS_PerlIO_get_layers)
646{
647 dXSARGS;
648 if (items < 1 || items % 2 == 0)
649 croak_xs_usage(cv, "filehandle[,args]");
650#if defined(USE_PERLIO)
651 {
652 SV * sv;
653 GV * gv;
654 IO * io;
655 bool input = TRUE;
656 bool details = FALSE;
657
658 if (items > 1) {
659 SV * const *svp;
660 for (svp = MARK + 2; svp <= SP; svp += 2) {
661 SV * const * const varp = svp;
662 SV * const * const valp = svp + 1;
663 STRLEN klen;
664 const char * const key = SvPV_const(*varp, klen);
665
666 switch (*key) {
667 case 'i':
668 if (klen == 5 && memEQ(key, "input", 5)) {
669 input = SvTRUE(*valp);
670 break;
671 }
672 goto fail;
673 case 'o':
674 if (klen == 6 && memEQ(key, "output", 6)) {
675 input = !SvTRUE(*valp);
676 break;
677 }
678 goto fail;
679 case 'd':
680 if (klen == 7 && memEQ(key, "details", 7)) {
681 details = SvTRUE(*valp);
682 break;
683 }
684 goto fail;
685 default:
686 fail:
687 Perl_croak(aTHX_
688 "get_layers: unknown argument '%s'",
689 key);
690 }
691 }
692
693 SP -= (items - 1);
694 }
695
696 sv = POPs;
697 gv = MAYBE_DEREF_GV(sv);
698
699 if (!gv && !SvROK(sv))
700 gv = gv_fetchsv_nomg(sv, 0, SVt_PVIO);
701
702 if (gv && (io = GvIO(gv))) {
703 AV* const av = PerlIO_get_layers(aTHX_ input ?
704 IoIFP(io) : IoOFP(io));
705 SSize_t i;
706 const SSize_t last = av_tindex(av);
707 SSize_t nitem = 0;
708
709 for (i = last; i >= 0; i -= 3) {
710 SV * const * const namsvp = av_fetch(av, i - 2, FALSE);
711 SV * const * const argsvp = av_fetch(av, i - 1, FALSE);
712 SV * const * const flgsvp = av_fetch(av, i, FALSE);
713
714 const bool namok = namsvp && *namsvp && SvPOK(*namsvp);
715 const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
716 const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
717
718 EXTEND(SP, 3); /* Three is the max in all branches: better check just once */
719 if (details) {
720 /* Indents of 5? Yuck. */
721 /* We know that PerlIO_get_layers creates a new SV for
722 the name and flags, so we can just take a reference
723 and "steal" it when we free the AV below. */
724 PUSHs(namok
725 ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
726 : &PL_sv_undef);
727 PUSHs(argok
728 ? newSVpvn_flags(SvPVX_const(*argsvp),
729 SvCUR(*argsvp),
730 (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
731 | SVs_TEMP)
732 : &PL_sv_undef);
733 PUSHs(flgok
734 ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
735 : &PL_sv_undef);
736 nitem += 3;
737 }
738 else {
739 if (namok && argok)
740 PUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
741 SVfARG(*namsvp),
742 SVfARG(*argsvp))));
743 else if (namok)
744 PUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
745 else
746 PUSHs(&PL_sv_undef);
747 nitem++;
748 if (flgok) {
749 const IV flags = SvIVX(*flgsvp);
750
751 if (flags & PERLIO_F_UTF8) {
752 PUSHs(newSVpvs_flags("utf8", SVs_TEMP));
753 nitem++;
754 }
755 }
756 }
757 }
758
759 SvREFCNT_dec(av);
760
761 XSRETURN(nitem);
762 }
763 }
764#endif
765
766 XSRETURN(0);
767}
768
769
770XS(XS_re_is_regexp); /* prototype to pass -Wmissing-prototypes */
771XS(XS_re_is_regexp)
772{
773 dXSARGS;
774 PERL_UNUSED_VAR(cv);
775
776 if (items != 1)
777 croak_xs_usage(cv, "sv");
778
779 if (SvRXOK(ST(0))) {
780 XSRETURN_YES;
781 } else {
782 XSRETURN_NO;
783 }
784}
785
786XS(XS_re_regnames_count); /* prototype to pass -Wmissing-prototypes */
787XS(XS_re_regnames_count)
788{
789 REGEXP *rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
790 SV * ret;
791 dXSARGS;
792
793 if (items != 0)
794 croak_xs_usage(cv, "");
795
796 SP -= items;
797 PUTBACK;
798
799 if (!rx)
800 XSRETURN_UNDEF;
801
802 ret = CALLREG_NAMED_BUFF_COUNT(rx);
803
804 SPAGAIN;
805 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
806 XSRETURN(1);
807}
808
809XS(XS_re_regname); /* prototype to pass -Wmissing-prototypes */
810XS(XS_re_regname)
811{
812 dXSARGS;
813 REGEXP * rx;
814 U32 flags;
815 SV * ret;
816
817 if (items < 1 || items > 2)
818 croak_xs_usage(cv, "name[, all ]");
819
820 SP -= items;
821 PUTBACK;
822
823 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
824
825 if (!rx)
826 XSRETURN_UNDEF;
827
828 if (items == 2 && SvTRUE(ST(1))) {
829 flags = RXapif_ALL;
830 } else {
831 flags = RXapif_ONE;
832 }
833 ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(0), (flags | RXapif_REGNAME));
834
835 SPAGAIN;
836 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
837 XSRETURN(1);
838}
839
840
841XS(XS_re_regnames); /* prototype to pass -Wmissing-prototypes */
842XS(XS_re_regnames)
843{
844 dXSARGS;
845 REGEXP * rx;
846 U32 flags;
847 SV *ret;
848 AV *av;
849 SSize_t length;
850 SSize_t i;
851 SV **entry;
852
853 if (items > 1)
854 croak_xs_usage(cv, "[all]");
855
856 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
857
858 if (!rx)
859 XSRETURN_UNDEF;
860
861 if (items == 1 && SvTRUE(ST(0))) {
862 flags = RXapif_ALL;
863 } else {
864 flags = RXapif_ONE;
865 }
866
867 SP -= items;
868 PUTBACK;
869
870 ret = CALLREG_NAMED_BUFF_ALL(rx, (flags | RXapif_REGNAMES));
871
872 SPAGAIN;
873
874 if (!ret)
875 XSRETURN_UNDEF;
876
877 av = MUTABLE_AV(SvRV(ret));
878 length = av_tindex(av);
879
880 EXTEND(SP, length+1); /* better extend stack just once */
881 for (i = 0; i <= length; i++) {
882 entry = av_fetch(av, i, FALSE);
883
884 if (!entry)
885 Perl_croak(aTHX_ "NULL array element in re::regnames()");
886
887 mPUSHs(SvREFCNT_inc_simple_NN(*entry));
888 }
889
890 SvREFCNT_dec(ret);
891
892 PUTBACK;
893 return;
894}
895
896XS(XS_re_regexp_pattern); /* prototype to pass -Wmissing-prototypes */
897XS(XS_re_regexp_pattern)
898{
899 dXSARGS;
900 REGEXP *re;
901 U8 const gimme = GIMME_V;
902
903 EXTEND(SP, 2);
904 SP -= items;
905 if (items != 1)
906 croak_xs_usage(cv, "sv");
907
908 /*
909 Checks if a reference is a regex or not. If the parameter is
910 not a ref, or is not the result of a qr// then returns false
911 in scalar context and an empty list in list context.
912 Otherwise in list context it returns the pattern and the
913 modifiers, in scalar context it returns the pattern just as it
914 would if the qr// was stringified normally, regardless as
915 to the class of the variable and any stringification overloads
916 on the object.
917 */
918
919 if ((re = SvRX(ST(0)))) /* assign deliberate */
920 {
921 /* Houston, we have a regex! */
922 SV *pattern;
923
924 if ( gimme == G_ARRAY ) {
925 STRLEN left = 0;
926 char reflags[sizeof(INT_PAT_MODS) + MAX_CHARSET_NAME_LENGTH];
927 const char *fptr;
928 char ch;
929 U16 match_flags;
930
931 /*
932 we are in list context so stringify
933 the modifiers that apply. We ignore "negative
934 modifiers" in this scenario, and the default character set
935 */
936
937 if (get_regex_charset(RX_EXTFLAGS(re)) != REGEX_DEPENDS_CHARSET) {
938 STRLEN len;
939 const char* const name = get_regex_charset_name(RX_EXTFLAGS(re),
940 &len);
941 Copy(name, reflags + left, len, char);
942 left += len;
943 }
944 fptr = INT_PAT_MODS;
945 match_flags = (U16)((RX_EXTFLAGS(re) & RXf_PMf_COMPILETIME)
946 >> RXf_PMf_STD_PMMOD_SHIFT);
947
948 while((ch = *fptr++)) {
949 if(match_flags & 1) {
950 reflags[left++] = ch;
951 }
952 match_flags >>= 1;
953 }
954
955 pattern = newSVpvn_flags(RX_PRECOMP(re),RX_PRELEN(re),
956 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
957
958 /* return the pattern and the modifiers */
959 PUSHs(pattern);
960 PUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
961 XSRETURN(2);
962 } else {
963 /* Scalar, so use the string that Perl would return */
964 /* return the pattern in (?msixn:..) format */
965#if PERL_VERSION >= 11
966 pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
967#else
968 pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
969 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
970#endif
971 PUSHs(pattern);
972 XSRETURN(1);
973 }
974 } else {
975 /* It ain't a regexp folks */
976 if ( gimme == G_ARRAY ) {
977 /* return the empty list */
978 XSRETURN_EMPTY;
979 } else {
980 /* Because of the (?:..) wrapping involved in a
981 stringified pattern it is impossible to get a
982 result for a real regexp that would evaluate to
983 false. Therefore we can return PL_sv_no to signify
984 that the object is not a regex, this means that one
985 can say
986
987 if (regex($might_be_a_regex) eq '(?:foo)') { }
988
989 and not worry about undefined values.
990 */
991 XSRETURN_NO;
992 }
993 }
994 NOT_REACHED; /* NOTREACHED */
995}
996
997#include "vutil.h"
998#include "vxs.inc"
999
1000struct xsub_details {
1001 const char *name;
1002 XSUBADDR_t xsub;
1003 const char *proto;
1004};
1005
1006static const struct xsub_details details[] = {
1007 {"UNIVERSAL::isa", XS_UNIVERSAL_isa, NULL},
1008 {"UNIVERSAL::can", XS_UNIVERSAL_can, NULL},
1009 {"UNIVERSAL::DOES", XS_UNIVERSAL_DOES, NULL},
1010#define VXS_XSUB_DETAILS
1011#include "vxs.inc"
1012#undef VXS_XSUB_DETAILS
1013 {"utf8::is_utf8", XS_utf8_is_utf8, NULL},
1014 {"utf8::valid", XS_utf8_valid, NULL},
1015 {"utf8::encode", XS_utf8_encode, NULL},
1016 {"utf8::decode", XS_utf8_decode, NULL},
1017 {"utf8::upgrade", XS_utf8_upgrade, NULL},
1018 {"utf8::downgrade", XS_utf8_downgrade, NULL},
1019 {"utf8::native_to_unicode", XS_utf8_native_to_unicode, NULL},
1020 {"utf8::unicode_to_native", XS_utf8_unicode_to_native, NULL},
1021 {"Internals::SvREADONLY", XS_Internals_SvREADONLY, "\\[$%@];$"},
1022 {"constant::_make_const", XS_constant__make_const, "\\[$@]"},
1023 {"Internals::SvREFCNT", XS_Internals_SvREFCNT, "\\[$%@];$"},
1024 {"Internals::hv_clear_placeholders", XS_Internals_hv_clear_placehold, "\\%"},
1025 {"PerlIO::get_layers", XS_PerlIO_get_layers, "*;@"},
1026 {"re::is_regexp", XS_re_is_regexp, "$"},
1027 {"re::regname", XS_re_regname, ";$$"},
1028 {"re::regnames", XS_re_regnames, ";$"},
1029 {"re::regnames_count", XS_re_regnames_count, ""},
1030 {"re::regexp_pattern", XS_re_regexp_pattern, "$"},
1031};
1032
1033STATIC OP*
1034optimize_out_native_convert_function(pTHX_ OP* entersubop,
1035 GV* namegv,
1036 SV* protosv)
1037{
1038 /* Optimizes out an identity function, i.e., one that just returns its
1039 * argument. The passed in function is assumed to be an identity function,
1040 * with no checking. This is designed to be called for utf8_to_native()
1041 * and native_to_utf8() on ASCII platforms, as they just return their
1042 * arguments, but it could work on any such function.
1043 *
1044 * The code is mostly just cargo-culted from Memoize::Lift */
1045
1046 OP *pushop, *argop;
1047 OP *parent;
1048 SV* prototype = newSVpvs("$");
1049
1050 PERL_UNUSED_ARG(protosv);
1051
1052 assert(entersubop->op_type == OP_ENTERSUB);
1053
1054 entersubop = ck_entersub_args_proto(entersubop, namegv, prototype);
1055 parent = entersubop;
1056
1057 SvREFCNT_dec(prototype);
1058
1059 pushop = cUNOPx(entersubop)->op_first;
1060 if (! OpHAS_SIBLING(pushop)) {
1061 parent = pushop;
1062 pushop = cUNOPx(pushop)->op_first;
1063 }
1064 argop = OpSIBLING(pushop);
1065
1066 /* Carry on without doing the optimization if it is not something we're
1067 * expecting, so continues to work */
1068 if ( ! argop
1069 || ! OpHAS_SIBLING(argop)
1070 || OpHAS_SIBLING(OpSIBLING(argop))
1071 ) {
1072 return entersubop;
1073 }
1074
1075 /* cut argop from the subtree */
1076 (void)op_sibling_splice(parent, pushop, 1, NULL);
1077
1078 op_free(entersubop);
1079 return argop;
1080}
1081
1082void
1083Perl_boot_core_UNIVERSAL(pTHX)
1084{
1085 static const char file[] = __FILE__;
1086 const struct xsub_details *xsub = details;
1087 const struct xsub_details *end = C_ARRAY_END(details);
1088
1089 do {
1090 newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
1091 } while (++xsub < end);
1092
1093#ifndef EBCDIC
1094 { /* On ASCII platforms these functions just return their argument, so can
1095 be optimized away */
1096
1097 CV* to_native_cv = get_cv("utf8::unicode_to_native", 0);
1098 CV* to_unicode_cv = get_cv("utf8::native_to_unicode", 0);
1099
1100 cv_set_call_checker(to_native_cv,
1101 optimize_out_native_convert_function,
1102 (SV*) to_native_cv);
1103 cv_set_call_checker(to_unicode_cv,
1104 optimize_out_native_convert_function,
1105 (SV*) to_unicode_cv);
1106 }
1107#endif
1108
1109 /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */
1110 {
1111 CV * const cv =
1112 newCONSTSUB(get_hv("Regexp::", GV_ADD), "DESTROY", NULL);
1113 char ** cvfile = &CvFILE(cv);
1114 char * oldfile = *cvfile;
1115 CvDYNFILE_off(cv);
1116 *cvfile = (char *)file;
1117 Safefree(oldfile);
1118 }
1119}
1120
1121/*
1122 * ex: set ts=8 sts=4 sw=4 et:
1123 */