This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge branch 'perlgov-omnibus-amendments' into blead
[perl5.git] / universal.c
CommitLineData
d6376244
JH
1/* universal.c
2 *
b5f8cc5c 3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
1129b882 4 * 2005, 2006, 2007, 2008 by Larry Wall and others
d6376244
JH
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
d31a8517 11/*
4ac71550
TC
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"]
d31a8517
AT
17 */
18
166f8a29
DM
19/* This file contains the code that implements the functions in Perl's
20 * UNIVERSAL package, such as UNIVERSAL->can().
192b9cd1
AB
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
486ec47a 24 * clever to move them to separate XS files which would then be pulled
192b9cd1 25 * in by some to-be-written build process.
166f8a29
DM
26 */
27
6d4a7be2 28#include "EXTERN.h"
864dbfa3 29#define PERL_IN_UNIVERSAL_C
6d4a7be2 30#include "perl.h"
6d4a7be2 31
97cb92d6 32#if defined(USE_PERLIO)
39f7a870
JH
33#include "perliol.h" /* For the PERLIO_F_XXX */
34#endif
35
6d4a7be2 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
c4b6b96d
SA
41#define PERL_ARGS_ASSERT_ISA_LOOKUP \
42 assert(stash); \
43 assert(namesv || name)
44
45
a9ec700e 46STATIC bool
c4b6b96d 47S_isa_lookup(pTHX_ HV *stash, SV *namesv, const char * name, STRLEN len, U32 flags)
6d4a7be2 48{
a49ba3fc 49 const struct mro_meta *const meta = HvMROMETA(stash);
4340b386 50 HV *isa = meta->isa;
a49ba3fc 51 const HV *our_stash;
6d4a7be2 52
7918f24d
NC
53 PERL_ARGS_ASSERT_ISA_LOOKUP;
54
4340b386 55 if (!isa) {
1604cfb0
MS
56 (void)mro_get_linear_isa(stash);
57 isa = meta->isa;
4340b386
FC
58 }
59
c4b6b96d 60 if (hv_common(isa, namesv, name, len, ( flags & SVf_UTF8 ? HVhek_UTF8 : 0),
1604cfb0
MS
61 HV_FETCH_ISEXISTS, NULL, 0)) {
62 /* Direct name lookup worked. */
63 return TRUE;
a49ba3fc 64 }
6d4a7be2 65
a49ba3fc 66 /* A stash/class can go by many names (ie. User == main::User), so
81a5123c
FC
67 we use the HvENAME in the stash itself, which is canonical, falling
68 back to HvNAME if necessary. */
c4b6b96d 69 our_stash = gv_stashsvpvn_cached(namesv, name, len, flags);
a49ba3fc
NC
70
71 if (our_stash) {
1604cfb0
MS
72 HEK *canon_name = HvENAME_HEK(our_stash);
73 if (!canon_name) canon_name = HvNAME_HEK(our_stash);
74 assert(canon_name);
75 if (hv_common(isa, NULL, HEK_KEY(canon_name), HEK_LEN(canon_name),
76 HEK_FLAGS(canon_name),
77 HV_FETCH_ISEXISTS, NULL, HEK_HASH(canon_name))) {
78 return TRUE;
79 }
6d4a7be2 80 }
81
a9ec700e 82 return FALSE;
6d4a7be2 83}
84
c4b6b96d
SA
85#define PERL_ARGS_ASSERT_SV_DERIVED_FROM_SVPVN \
86 assert(sv); \
87 assert(namesv || name)
88
89STATIC bool
90S_sv_derived_from_svpvn(pTHX_ SV *sv, SV *namesv, const char * name, const STRLEN len, U32 flags)
91{
92 HV* stash;
93
94 PERL_ARGS_ASSERT_SV_DERIVED_FROM_SVPVN;
95 SvGETMAGIC(sv);
96
97 if (SvROK(sv)) {
98 const char *type;
99 sv = SvRV(sv);
100 type = sv_reftype(sv,0);
101 if (type) {
102 if (namesv)
103 name = SvPV_nolen(namesv);
104 if (strEQ(name, type))
105 return TRUE;
106 }
107 if (!SvOBJECT(sv))
108 return FALSE;
109 stash = SvSTASH(sv);
110 }
111 else {
112 stash = gv_stashsv(sv, 0);
113 }
114
115 if (stash && isa_lookup(stash, namesv, name, len, flags))
116 return TRUE;
117
118 stash = gv_stashpvs("UNIVERSAL", 0);
119 return stash && isa_lookup(stash, namesv, name, len, flags);
120}
121
954c1994 122/*
3f620621 123=for apidoc_section $SV
ccfc67b7 124
c7abbf64 125=for apidoc sv_derived_from_pvn
954c1994 126
6885da0e 127Returns a boolean indicating whether the SV is derived from the specified class
128I<at the C level>. To check derivation at the Perl level, call C<isa()> as a
129normal Perl method.
954c1994 130
c7abbf64
BF
131Currently, the only significant value for C<flags> is SVf_UTF8.
132
133=cut
134
135=for apidoc sv_derived_from_sv
136
137Exactly like L</sv_derived_from_pvn>, but takes the name string in the form
c4b6b96d 138of an SV instead of a string/length pair. This is the advised form.
c7abbf64
BF
139
140=cut
141
142*/
143
144bool
145Perl_sv_derived_from_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
146{
c7abbf64 147 PERL_ARGS_ASSERT_SV_DERIVED_FROM_SV;
c4b6b96d 148 return sv_derived_from_svpvn(sv, namesv, NULL, 0, flags);
c7abbf64
BF
149}
150
151/*
152=for apidoc sv_derived_from
153
154Exactly like L</sv_derived_from_pv>, but doesn't take a C<flags> parameter.
155
954c1994
GS
156=cut
157*/
158
55497cff 159bool
15f169a1 160Perl_sv_derived_from(pTHX_ SV *sv, const char *const name)
55497cff 161{
c7abbf64 162 PERL_ARGS_ASSERT_SV_DERIVED_FROM;
c4b6b96d 163 return sv_derived_from_svpvn(sv, NULL, name, strlen(name), 0);
c7abbf64
BF
164}
165
166/*
167=for apidoc sv_derived_from_pv
168
169Exactly like L</sv_derived_from_pvn>, but takes a nul-terminated string
170instead of a string/length pair.
171
172=cut
173*/
174
175
176bool
177Perl_sv_derived_from_pv(pTHX_ SV *sv, const char *const name, U32 flags)
178{
179 PERL_ARGS_ASSERT_SV_DERIVED_FROM_PV;
c4b6b96d 180 return sv_derived_from_svpvn(sv, NULL, name, strlen(name), flags);
c7abbf64
BF
181}
182
183bool
184Perl_sv_derived_from_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len, U32 flags)
185{
c7abbf64 186 PERL_ARGS_ASSERT_SV_DERIVED_FROM_PVN;
c4b6b96d 187 return sv_derived_from_svpvn(sv, NULL, name, len, flags);
55497cff 188}
189
cbc021f9 190/*
813e85a0
PE
191=for apidoc sv_isa_sv
192
193Returns a boolean indicating whether the SV is an object reference and is
194derived from the specified class, respecting any C<isa()> method overloading
195it may have. Returns false if C<sv> is not a reference to an object, or is
196not derived from the specified class.
197
198This is the function used to implement the behaviour of the C<isa> operator.
199
11fcdeb9
PE
200Does not invoke magic on C<sv>.
201
813e85a0
PE
202Not to be confused with the older C<sv_isa> function, which does not use an
203overloaded C<isa()> method, nor will check subclassing.
204
205=cut
206
207*/
208
209bool
210Perl_sv_isa_sv(pTHX_ SV *sv, SV *namesv)
211{
212 GV *isagv;
213
214 PERL_ARGS_ASSERT_SV_ISA_SV;
215
216 if(!SvROK(sv) || !SvOBJECT(SvRV(sv)))
217 return FALSE;
218
5f65868c 219 isagv = gv_fetchmeth_pvn(SvSTASH(SvRV(sv)), "isa", 3, -1, GV_NOUNIVERSAL);
813e85a0
PE
220 if(isagv) {
221 dSP;
222 CV *isacv = isGV(isagv) ? GvCV(isagv) : (CV *)isagv;
223 SV *retsv;
224 bool ret;
225
226 PUTBACK;
227
228 ENTER;
229 SAVETMPS;
230
231 EXTEND(SP, 2);
232 PUSHMARK(SP);
233 PUSHs(sv);
234 PUSHs(namesv);
235 PUTBACK;
236
237 call_sv((SV *)isacv, G_SCALAR);
238
239 SPAGAIN;
240 retsv = POPs;
241 ret = SvTRUE(retsv);
242 PUTBACK;
243
244 FREETMPS;
245 LEAVE;
246
247 return ret;
248 }
249
250 /* TODO: Support namesv being an HV ref to the stash directly? */
251
252 return sv_derived_from_sv(sv, namesv, 0);
253}
254
255/*
d20c2c29 256=for apidoc sv_does_sv
cbc021f9 257
258Returns a boolean indicating whether the SV performs a specific, named role.
259The SV can be a Perl object or the name of a Perl class.
260
261=cut
262*/
263
1b026014
NIS
264#include "XSUB.h"
265
cbc021f9 266bool
f778bcfd 267Perl_sv_does_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
cbc021f9 268{
f778bcfd 269 SV *classname;
cbc021f9 270 bool does_it;
59e7186f 271 SV *methodname;
cbc021f9 272 dSP;
7918f24d 273
f778bcfd
BF
274 PERL_ARGS_ASSERT_SV_DOES_SV;
275 PERL_UNUSED_ARG(flags);
7918f24d 276
cbc021f9 277 ENTER;
278 SAVETMPS;
279
280 SvGETMAGIC(sv);
281
d96ab1b5 282 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv)))) {
1604cfb0
MS
283 LEAVE;
284 return FALSE;
7ce46f2a 285 }
cbc021f9 286
4b523e79 287 if (SvROK(sv) && SvOBJECT(SvRV(sv))) {
1604cfb0 288 classname = sv_ref(NULL,SvRV(sv),TRUE);
cbc021f9 289 } else {
1604cfb0 290 classname = sv;
cbc021f9 291 }
292
f778bcfd 293 if (sv_eq(classname, namesv)) {
1604cfb0
MS
294 LEAVE;
295 return TRUE;
7ce46f2a 296 }
cbc021f9 297
298 PUSHMARK(SP);
f778bcfd
BF
299 EXTEND(SP, 2);
300 PUSHs(sv);
301 PUSHs(namesv);
cbc021f9 302 PUTBACK;
303
9a70c74b 304 /* create a PV with value "isa", but with a special address
7fd883b1 305 * so that perl knows we're really doing "DOES" instead */
9a70c74b 306 methodname = newSV_type(SVt_PV);
59c3c222
N
307 SvLEN_set(methodname, 0);
308 SvCUR_set(methodname, strlen(PL_isa_DOES));
7bfe3bfd 309 SvPVX(methodname) = (char *)PL_isa_DOES; /* discard 'const' qualifier */
9a70c74b
DM
310 SvPOK_on(methodname);
311 sv_2mortal(methodname);
59e7186f 312 call_sv(methodname, G_SCALAR | G_METHOD);
cbc021f9 313 SPAGAIN;
314
f4c975aa 315 does_it = SvTRUE_NN( TOPs );
cbc021f9 316 FREETMPS;
317 LEAVE;
318
319 return does_it;
320}
321
afa74d42 322/*
f778bcfd
BF
323=for apidoc sv_does
324
d20c2c29 325Like L</sv_does_pv>, but doesn't take a C<flags> parameter.
f778bcfd
BF
326
327=cut
328*/
329
330bool
331Perl_sv_does(pTHX_ SV *sv, const char *const name)
332{
333 PERL_ARGS_ASSERT_SV_DOES;
334 return sv_does_sv(sv, newSVpvn_flags(name, strlen(name), SVs_TEMP), 0);
335}
336
337/*
338=for apidoc sv_does_pv
339
7d892b8c 340Like L</sv_does_sv>, but takes a nul-terminated string instead of an SV.
f778bcfd
BF
341
342=cut
343*/
344
345
346bool
347Perl_sv_does_pv(pTHX_ SV *sv, const char *const name, U32 flags)
348{
349 PERL_ARGS_ASSERT_SV_DOES_PV;
350 return sv_does_sv(sv, newSVpvn_flags(name, strlen(name), SVs_TEMP | flags), flags);
351}
352
7d892b8c
FC
353/*
354=for apidoc sv_does_pvn
355
356Like L</sv_does_sv>, but takes a string/length pair instead of an SV.
357
358=cut
359*/
360
f778bcfd
BF
361bool
362Perl_sv_does_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len, U32 flags)
363{
364 PERL_ARGS_ASSERT_SV_DOES_PVN;
365
366 return sv_does_sv(sv, newSVpvn_flags(name, len, flags | SVs_TEMP), flags);
367}
368
369/*
afa74d42
NC
370=for apidoc croak_xs_usage
371
372A specialised variant of C<croak()> for emitting the usage message for xsubs
373
374 croak_xs_usage(cv, "eee_yow");
375
376works out the package name and subroutine name from C<cv>, and then calls
72d33970 377C<croak()>. Hence if C<cv> is C<&ouch::awk>, it would call C<croak> as:
afa74d42 378
147e3846 379 Perl_croak(aTHX_ "Usage: %" SVf "::%" SVf "(%s)", "ouch" "awk",
8560fbdd 380 "eee_yow");
afa74d42
NC
381
382=cut
383*/
384
385void
cb077ed2 386Perl_croak_xs_usage(const CV *const cv, const char *const params)
afa74d42 387{
ae77754a 388 /* Avoid CvGV as it requires aTHX. */
2eaf799e 389 const GV *gv = CvNAMED(cv) ? NULL : cv->sv_any->xcv_gv_u.xcv_gv;
afa74d42
NC
390
391 PERL_ARGS_ASSERT_CROAK_XS_USAGE;
392
2eaf799e 393 if (gv) got_gv: {
1604cfb0 394 const HV *const stash = GvSTASH(gv);
afa74d42 395
1604cfb0
MS
396 if (HvNAME_get(stash))
397 /* diag_listed_as: SKIPME */
398 Perl_croak_nocontext("Usage: %" HEKf "::%" HEKf "(%s)",
d0c0e7dd
FC
399 HEKfARG(HvNAME_HEK(stash)),
400 HEKfARG(GvNAME_HEK(gv)),
58cb15b3 401 params);
1604cfb0
MS
402 else
403 /* diag_listed_as: SKIPME */
404 Perl_croak_nocontext("Usage: %" HEKf "(%s)",
d0c0e7dd 405 HEKfARG(GvNAME_HEK(gv)), params);
afa74d42 406 } else {
2eaf799e
FC
407 dTHX;
408 if ((gv = CvGV(cv))) goto got_gv;
409
1604cfb0
MS
410 /* Pants. I don't think that it should be possible to get here. */
411 /* diag_listed_as: SKIPME */
412 Perl_croak(aTHX_ "Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
afa74d42
NC
413 }
414}
55497cff 415
15eb3045 416XS(XS_UNIVERSAL_isa); /* prototype to pass -Wmissing-prototypes */
6d4a7be2 417XS(XS_UNIVERSAL_isa)
418{
419 dXSARGS;
6d4a7be2 420
421 if (items != 2)
1604cfb0 422 croak_xs_usage(cv, "reference, kind");
c4420975 423 else {
1604cfb0 424 SV * const sv = ST(0);
6d4a7be2 425
1604cfb0 426 SvGETMAGIC(sv);
d3f7f2b2 427
1604cfb0
MS
428 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))))
429 XSRETURN_UNDEF;
f8f70380 430
1604cfb0
MS
431 ST(0) = boolSV(sv_derived_from_sv(sv, ST(1), 0));
432 XSRETURN(1);
c4420975 433 }
6d4a7be2 434}
435
15eb3045 436XS(XS_UNIVERSAL_can); /* prototype to pass -Wmissing-prototypes */
6d4a7be2 437XS(XS_UNIVERSAL_can)
438{
439 dXSARGS;
440 SV *sv;
6d4a7be2 441 SV *rv;
6f08146e 442 HV *pkg = NULL;
2bde9ae6 443 GV *iogv;
6d4a7be2 444
445 if (items != 2)
1604cfb0 446 croak_xs_usage(cv, "object-ref, method");
6d4a7be2 447
448 sv = ST(0);
f8f70380 449
5b295bef 450 SvGETMAGIC(sv);
d3f7f2b2 451
4178f891
FC
452 /* Reject undef and empty string. Note that the string form takes
453 precedence here over the numeric form, as (!1)->foo treats the
454 invocant as the empty string, though it is a dualvar. */
455 if (!SvOK(sv) || (SvPOK(sv) && !SvCUR(sv)))
1604cfb0 456 XSRETURN_UNDEF;
f8f70380 457
3280af22 458 rv = &PL_sv_undef;
6d4a7be2 459
46e4b22b 460 if (SvROK(sv)) {
daba3364 461 sv = MUTABLE_SV(SvRV(sv));
46e4b22b 462 if (SvOBJECT(sv))
6f08146e 463 pkg = SvSTASH(sv);
4178f891 464 else if (isGV_with_GP(sv) && GvIO(sv))
1604cfb0 465 pkg = SvSTASH(GvIO(sv));
6f08146e 466 }
4178f891
FC
467 else if (isGV_with_GP(sv) && GvIO(sv))
468 pkg = SvSTASH(GvIO(sv));
2bde9ae6
FC
469 else if ((iogv = gv_fetchsv_nomg(sv, 0, SVt_PVIO)) && GvIO(iogv))
470 pkg = SvSTASH(GvIO(iogv));
6f08146e 471 else {
da51bb9b 472 pkg = gv_stashsv(sv, 0);
68b40612 473 if (!pkg)
7d59d161 474 pkg = gv_stashpvs("UNIVERSAL", 0);
6f08146e
NIS
475 }
476
477 if (pkg) {
1604cfb0 478 GV * const gv = gv_fetchmethod_sv_flags(pkg, ST(1), 0);
dc848c6f 479 if (gv && isGV(gv))
1604cfb0 480 rv = sv_2mortal(newRV(MUTABLE_SV(GvCV(gv))));
6d4a7be2 481 }
482
483 ST(0) = rv;
484 XSRETURN(1);
485}
486
15eb3045 487XS(XS_UNIVERSAL_DOES); /* prototype to pass -Wmissing-prototypes */
cbc021f9 488XS(XS_UNIVERSAL_DOES)
489{
cbc021f9 490 dXSARGS;
58c0efa5 491 PERL_UNUSED_ARG(cv);
cbc021f9 492
493 if (items != 2)
1604cfb0 494 Perl_croak(aTHX_ "Usage: invocant->DOES(kind)");
cbc021f9 495 else {
1604cfb0
MS
496 SV * const sv = ST(0);
497 if (sv_does_sv( sv, ST(1), 0 ))
498 XSRETURN_YES;
cbc021f9 499
1604cfb0 500 XSRETURN_NO;
cbc021f9 501 }
502}
503
15eb3045 504XS(XS_utf8_is_utf8); /* prototype to pass -Wmissing-prototypes */
8800c35a
JH
505XS(XS_utf8_is_utf8)
506{
41be1fbd
JH
507 dXSARGS;
508 if (items != 1)
1604cfb0 509 croak_xs_usage(cv, "sv");
c4420975 510 else {
1604cfb0
MS
511 SV * const sv = ST(0);
512 SvGETMAGIC(sv);
513 if (SvUTF8(sv))
514 XSRETURN_YES;
515 else
516 XSRETURN_NO;
41be1fbd
JH
517 }
518 XSRETURN_EMPTY;
8800c35a
JH
519}
520
15eb3045 521XS(XS_utf8_valid); /* prototype to pass -Wmissing-prototypes */
1b026014
NIS
522XS(XS_utf8_valid)
523{
41be1fbd
JH
524 dXSARGS;
525 if (items != 1)
1604cfb0 526 croak_xs_usage(cv, "sv");
c4420975 527 else {
1604cfb0
MS
528 SV * const sv = ST(0);
529 STRLEN len;
530 const char * const s = SvPV_const(sv,len);
531 if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len))
532 XSRETURN_YES;
533 else
534 XSRETURN_NO;
c4420975 535 }
41be1fbd 536 XSRETURN_EMPTY;
1b026014
NIS
537}
538
15eb3045 539XS(XS_utf8_encode); /* prototype to pass -Wmissing-prototypes */
1b026014
NIS
540XS(XS_utf8_encode)
541{
542 dXSARGS;
543 if (items != 1)
1604cfb0 544 croak_xs_usage(cv, "sv");
c4420975 545 sv_utf8_encode(ST(0));
892f9127 546 SvSETMAGIC(ST(0));
1b026014
NIS
547 XSRETURN_EMPTY;
548}
549
15eb3045 550XS(XS_utf8_decode); /* prototype to pass -Wmissing-prototypes */
1b026014
NIS
551XS(XS_utf8_decode)
552{
553 dXSARGS;
554 if (items != 1)
1604cfb0 555 croak_xs_usage(cv, "sv");
c4420975 556 else {
1604cfb0
MS
557 SV * const sv = ST(0);
558 bool RETVAL;
559 SvPV_force_nolen(sv);
560 RETVAL = sv_utf8_decode(sv);
561 SvSETMAGIC(sv);
562 ST(0) = boolSV(RETVAL);
1b026014
NIS
563 }
564 XSRETURN(1);
565}
566
15eb3045 567XS(XS_utf8_upgrade); /* prototype to pass -Wmissing-prototypes */
1b026014
NIS
568XS(XS_utf8_upgrade)
569{
570 dXSARGS;
571 if (items != 1)
1604cfb0 572 croak_xs_usage(cv, "sv");
c4420975 573 else {
1604cfb0
MS
574 SV * const sv = ST(0);
575 STRLEN RETVAL;
576 dXSTARG;
1b026014 577
1604cfb0
MS
578 RETVAL = sv_utf8_upgrade(sv);
579 XSprePUSH; PUSHi((IV)RETVAL);
1b026014
NIS
580 }
581 XSRETURN(1);
582}
583
15eb3045 584XS(XS_utf8_downgrade); /* prototype to pass -Wmissing-prototypes */
1b026014
NIS
585XS(XS_utf8_downgrade)
586{
587 dXSARGS;
588 if (items < 1 || items > 2)
1604cfb0 589 croak_xs_usage(cv, "sv, failok=0");
c4420975 590 else {
1604cfb0
MS
591 SV * const sv0 = ST(0);
592 SV * const sv1 = ST(1);
f4c975aa
DM
593 const bool failok = (items < 2) ? 0 : SvTRUE_NN(sv1) ? 1 : 0;
594 const bool RETVAL = sv_utf8_downgrade(sv0, failok);
1b026014 595
1604cfb0 596 ST(0) = boolSV(RETVAL);
1b026014
NIS
597 }
598 XSRETURN(1);
599}
600
15eb3045 601XS(XS_utf8_native_to_unicode); /* prototype to pass -Wmissing-prototypes */
1b026014
NIS
602XS(XS_utf8_native_to_unicode)
603{
604 dXSARGS;
6867be6d 605 const UV uv = SvUV(ST(0));
b7953727
JH
606
607 if (items > 1)
afa74d42 608 croak_xs_usage(cv, "sv");
b7953727 609
b5804ad6 610 ST(0) = sv_2mortal(newSVuv(NATIVE_TO_UNI(uv)));
1b026014
NIS
611 XSRETURN(1);
612}
613
15eb3045 614XS(XS_utf8_unicode_to_native); /* prototype to pass -Wmissing-prototypes */
1b026014
NIS
615XS(XS_utf8_unicode_to_native)
616{
617 dXSARGS;
6867be6d 618 const UV uv = SvUV(ST(0));
b7953727
JH
619
620 if (items > 1)
afa74d42 621 croak_xs_usage(cv, "sv");
b7953727 622
b5804ad6 623 ST(0) = sv_2mortal(newSVuv(UNI_TO_NATIVE(uv)));
1b026014
NIS
624 XSRETURN(1);
625}
626
15eb3045 627XS(XS_Internals_SvREADONLY); /* prototype to pass -Wmissing-prototypes */
14a976d6 628XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
29569577
JH
629{
630 dXSARGS;
80b6a949
AB
631 SV * const svz = ST(0);
632 SV * sv;
6867be6d 633
80b6a949
AB
634 /* [perl #77776] - called as &foo() not foo() */
635 if (!SvROK(svz))
636 croak_xs_usage(cv, "SCALAR[, ON]");
637
638 sv = SvRV(svz);
639
29569577 640 if (items == 1) {
1604cfb0
MS
641 if (SvREADONLY(sv))
642 XSRETURN_YES;
643 else
644 XSRETURN_NO;
29569577
JH
645 }
646 else if (items == 2) {
f4c975aa 647 SV *sv1 = ST(1);
1604cfb0
MS
648 if (SvTRUE_NN(sv1)) {
649 SvFLAGS(sv) |= SVf_READONLY;
650 XSRETURN_YES;
651 }
652 else {
653 /* I hope you really know what you are doing. */
654 SvFLAGS(sv) &=~ SVf_READONLY;
655 XSRETURN_NO;
656 }
29569577 657 }
14a976d6 658 XSRETURN_UNDEF; /* Can't happen. */
29569577 659}
2c6c1df5 660
15eb3045 661XS(XS_constant__make_const); /* prototype to pass -Wmissing-prototypes */
2c6c1df5
FC
662XS(XS_constant__make_const) /* This is dangerous stuff. */
663{
2c6c1df5
FC
664 dXSARGS;
665 SV * const svz = ST(0);
666 SV * sv;
2c6c1df5
FC
667
668 /* [perl #77776] - called as &foo() not foo() */
669 if (!SvROK(svz) || items != 1)
670 croak_xs_usage(cv, "SCALAR");
671
672 sv = SvRV(svz);
673
2c6c1df5
FC
674 SvREADONLY_on(sv);
675 if (SvTYPE(sv) == SVt_PVAV && AvFILLp(sv) != -1) {
1604cfb0
MS
676 /* for constant.pm; nobody else should be calling this
677 on arrays anyway. */
678 SV **svp;
679 for (svp = AvARRAY(sv) + AvFILLp(sv)
680 ; svp >= AvARRAY(sv)
681 ; --svp)
682 if (*svp) SvPADTMP_on(*svp);
2c6c1df5
FC
683 }
684 XSRETURN(0);
685}
686
15eb3045 687XS(XS_Internals_SvREFCNT); /* prototype to pass -Wmissing-prototypes */
14a976d6 688XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
29569577
JH
689{
690 dXSARGS;
80b6a949
AB
691 SV * const svz = ST(0);
692 SV * sv;
fa3febb6 693 U32 refcnt;
6867be6d 694
80b6a949 695 /* [perl #77776] - called as &foo() not foo() */
fa3febb6 696 if ((items != 1 && items != 2) || !SvROK(svz))
80b6a949
AB
697 croak_xs_usage(cv, "SCALAR[, REFCOUNT]");
698
699 sv = SvRV(svz);
700
14a976d6 701 /* I hope you really know what you are doing. */
fa3febb6
DD
702 /* idea is for SvREFCNT(sv) to be accessed only once */
703 refcnt = items == 2 ?
704 /* we free one ref on exit */
705 (SvREFCNT(sv) = SvUV(ST(1)) + 1)
706 : SvREFCNT(sv);
707 XSRETURN_UV(refcnt - 1); /* Minus the ref created for us. */
708
29569577
JH
709}
710
e312a16a
YO
711XS(XS_Internals_hv_clear_placehold); /* prototype to pass -Wmissing-prototypes */
712XS(XS_Internals_hv_clear_placehold)
713{
714 dXSARGS;
715
716 if (items != 1 || !SvROK(ST(0)))
1604cfb0 717 croak_xs_usage(cv, "hv");
e312a16a 718 else {
1604cfb0
MS
719 HV * const hv = MUTABLE_HV(SvRV(ST(0)));
720 hv_clear_placeholders(hv);
721 XSRETURN(0);
e312a16a
YO
722 }
723}
724
15eb3045 725XS(XS_PerlIO_get_layers); /* prototype to pass -Wmissing-prototypes */
39f7a870
JH
726XS(XS_PerlIO_get_layers)
727{
728 dXSARGS;
729 if (items < 1 || items % 2 == 0)
1604cfb0 730 croak_xs_usage(cv, "filehandle[,args]");
97cb92d6 731#if defined(USE_PERLIO)
39f7a870 732 {
1604cfb0
MS
733 SV * sv;
734 GV * gv;
735 IO * io;
736 bool input = TRUE;
737 bool details = FALSE;
738
739 if (items > 1) {
740 SV * const *svp;
741 for (svp = MARK + 2; svp <= SP; svp += 2) {
742 SV * const * const varp = svp;
743 SV * const * const valp = svp + 1;
744 STRLEN klen;
745 const char * const key = SvPV_const(*varp, klen);
746
747 switch (*key) {
748 case 'i':
fd9f609b 749 if (memEQs(key, klen, "input")) {
1604cfb0
MS
750 input = SvTRUE(*valp);
751 break;
752 }
753 goto fail;
754 case 'o':
fd9f609b 755 if (memEQs(key, klen, "output")) {
1604cfb0
MS
756 input = !SvTRUE(*valp);
757 break;
758 }
759 goto fail;
760 case 'd':
fd9f609b 761 if (memEQs(key, klen, "details")) {
1604cfb0
MS
762 details = SvTRUE(*valp);
763 break;
764 }
765 goto fail;
766 default:
767 fail:
768 Perl_croak(aTHX_
769 "get_layers: unknown argument '%s'",
770 key);
771 }
772 }
773
774 SP -= (items - 1);
775 }
776
777 sv = POPs;
778 gv = MAYBE_DEREF_GV(sv);
779
780 if (!gv && !SvROK(sv))
781 gv = gv_fetchsv_nomg(sv, 0, SVt_PVIO);
782
783 if (gv && (io = GvIO(gv))) {
784 AV* const av = PerlIO_get_layers(aTHX_ input ?
785 IoIFP(io) : IoOFP(io));
786 SSize_t i;
787 const SSize_t last = av_top_index(av);
788 SSize_t nitem = 0;
789
790 for (i = last; i >= 0; i -= 3) {
791 SV * const * const namsvp = av_fetch(av, i - 2, FALSE);
792 SV * const * const argsvp = av_fetch(av, i - 1, FALSE);
793 SV * const * const flgsvp = av_fetch(av, i, FALSE);
794
795 const bool namok = namsvp && *namsvp && SvPOK(*namsvp);
796 const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
797 const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
798
799 EXTEND(SP, 3); /* Three is the max in all branches: better check just once */
800 if (details) {
801 /* Indents of 5? Yuck. */
802 /* We know that PerlIO_get_layers creates a new SV for
803 the name and flags, so we can just take a reference
804 and "steal" it when we free the AV below. */
805 PUSHs(namok
806 ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
807 : &PL_sv_undef);
808 PUSHs(argok
809 ? newSVpvn_flags(SvPVX_const(*argsvp),
810 SvCUR(*argsvp),
811 (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
812 | SVs_TEMP)
813 : &PL_sv_undef);
814 PUSHs(flgok
815 ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
816 : &PL_sv_undef);
817 nitem += 3;
818 }
819 else {
820 if (namok && argok)
821 PUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%" SVf "(%" SVf ")",
822 SVfARG(*namsvp),
823 SVfARG(*argsvp))));
824 else if (namok)
825 PUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
826 else
827 PUSHs(&PL_sv_undef);
828 nitem++;
829 if (flgok) {
830 const IV flags = SvIVX(*flgsvp);
831
832 if (flags & PERLIO_F_UTF8) {
833 PUSHs(newSVpvs_flags("utf8", SVs_TEMP));
834 nitem++;
835 }
836 }
837 }
838 }
839
840 SvREFCNT_dec(av);
841
842 XSRETURN(nitem);
843 }
39f7a870 844 }
5fef3b4a 845#endif
39f7a870
JH
846
847 XSRETURN(0);
848}
849
15eb3045 850XS(XS_re_is_regexp); /* prototype to pass -Wmissing-prototypes */
80305961
YO
851XS(XS_re_is_regexp)
852{
80305961 853 dXSARGS;
f7e71195 854
80305961 855 if (items != 1)
1604cfb0 856 croak_xs_usage(cv, "sv");
f7e71195 857
f7e71195
AB
858 if (SvRXOK(ST(0))) {
859 XSRETURN_YES;
860 } else {
861 XSRETURN_NO;
80305961
YO
862 }
863}
864
15eb3045 865XS(XS_re_regnames_count); /* prototype to pass -Wmissing-prototypes */
192b9cd1 866XS(XS_re_regnames_count)
80305961 867{
192b9cd1
AB
868 REGEXP *rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
869 SV * ret;
80305961 870 dXSARGS;
192b9cd1
AB
871
872 if (items != 0)
1604cfb0 873 croak_xs_usage(cv, "");
192b9cd1 874
192b9cd1
AB
875 if (!rx)
876 XSRETURN_UNDEF;
877
878 ret = CALLREG_NAMED_BUFF_COUNT(rx);
879
880 SPAGAIN;
fdae9473
NC
881 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
882 XSRETURN(1);
192b9cd1
AB
883}
884
15eb3045 885XS(XS_re_regname); /* prototype to pass -Wmissing-prototypes */
192b9cd1
AB
886XS(XS_re_regname)
887{
192b9cd1
AB
888 dXSARGS;
889 REGEXP * rx;
890 U32 flags;
891 SV * ret;
892
28d8d7f4 893 if (items < 1 || items > 2)
1604cfb0 894 croak_xs_usage(cv, "name[, all ]");
192b9cd1 895
80305961 896 SP -= items;
fdae9473 897 PUTBACK;
80305961 898
192b9cd1
AB
899 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
900
901 if (!rx)
902 XSRETURN_UNDEF;
903
f4c975aa 904 if (items == 2 && SvTRUE_NN(ST(1))) {
f1b875a0 905 flags = RXapif_ALL;
192b9cd1 906 } else {
f1b875a0 907 flags = RXapif_ONE;
80305961 908 }
f1b875a0 909 ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(0), (flags | RXapif_REGNAME));
192b9cd1 910
fdae9473
NC
911 SPAGAIN;
912 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
913 XSRETURN(1);
80305961
YO
914}
915
192b9cd1 916
15eb3045 917XS(XS_re_regnames); /* prototype to pass -Wmissing-prototypes */
80305961
YO
918XS(XS_re_regnames)
919{
80305961 920 dXSARGS;
192b9cd1
AB
921 REGEXP * rx;
922 U32 flags;
923 SV *ret;
924 AV *av;
c70927a6
FC
925 SSize_t length;
926 SSize_t i;
192b9cd1
AB
927 SV **entry;
928
929 if (items > 1)
1604cfb0 930 croak_xs_usage(cv, "[all]");
192b9cd1
AB
931
932 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
933
934 if (!rx)
935 XSRETURN_UNDEF;
936
f4c975aa 937 if (items == 1 && SvTRUE_NN(ST(0))) {
f1b875a0 938 flags = RXapif_ALL;
192b9cd1 939 } else {
f1b875a0 940 flags = RXapif_ONE;
192b9cd1
AB
941 }
942
80305961 943 SP -= items;
fdae9473 944 PUTBACK;
80305961 945
f1b875a0 946 ret = CALLREG_NAMED_BUFF_ALL(rx, (flags | RXapif_REGNAMES));
192b9cd1
AB
947
948 SPAGAIN;
949
192b9cd1
AB
950 if (!ret)
951 XSRETURN_UNDEF;
952
502c6561 953 av = MUTABLE_AV(SvRV(ret));
d4371c8e 954 length = av_count(av);
192b9cd1 955
d4371c8e
KW
956 EXTEND(SP, length); /* better extend stack just once */
957 for (i = 0; i < length; i++) {
192b9cd1
AB
958 entry = av_fetch(av, i, FALSE);
959
960 if (!entry)
961 Perl_croak(aTHX_ "NULL array element in re::regnames()");
962
2102d7a2 963 mPUSHs(SvREFCNT_inc_simple_NN(*entry));
80305961 964 }
ec83ea38
MHM
965
966 SvREFCNT_dec(ret);
967
192b9cd1
AB
968 PUTBACK;
969 return;
80305961
YO
970}
971
15eb3045 972XS(XS_re_regexp_pattern); /* prototype to pass -Wmissing-prototypes */
192c1e27
JH
973XS(XS_re_regexp_pattern)
974{
192c1e27
JH
975 dXSARGS;
976 REGEXP *re;
1c23e2bd 977 U8 const gimme = GIMME_V;
192c1e27 978
22d874e2
DD
979 EXTEND(SP, 2);
980 SP -= items;
192c1e27 981 if (items != 1)
1604cfb0 982 croak_xs_usage(cv, "sv");
192c1e27 983
192c1e27
JH
984 /*
985 Checks if a reference is a regex or not. If the parameter is
986 not a ref, or is not the result of a qr// then returns false
987 in scalar context and an empty list in list context.
988 Otherwise in list context it returns the pattern and the
989 modifiers, in scalar context it returns the pattern just as it
990 would if the qr// was stringified normally, regardless as
486ec47a 991 to the class of the variable and any stringification overloads
192c1e27
JH
992 on the object.
993 */
994
995 if ((re = SvRX(ST(0)))) /* assign deliberate */
996 {
22c985d5 997 /* Houston, we have a regex! */
192c1e27 998 SV *pattern;
192c1e27 999
eb7e169e 1000 if ( gimme == G_LIST ) {
1604cfb0
MS
1001 STRLEN left = 0;
1002 char reflags[sizeof(INT_PAT_MODS) + MAX_CHARSET_NAME_LENGTH];
69af1167
SH
1003 const char *fptr;
1004 char ch;
1005 U16 match_flags;
1006
192c1e27
JH
1007 /*
1008 we are in list context so stringify
1009 the modifiers that apply. We ignore "negative
a62b1201 1010 modifiers" in this scenario, and the default character set
192c1e27
JH
1011 */
1012
1604cfb0
MS
1013 if (get_regex_charset(RX_EXTFLAGS(re)) != REGEX_DEPENDS_CHARSET) {
1014 STRLEN len;
1015 const char* const name = get_regex_charset_name(RX_EXTFLAGS(re),
1016 &len);
1017 Copy(name, reflags + left, len, char);
1018 left += len;
1019 }
69af1167 1020 fptr = INT_PAT_MODS;
73134a2e 1021 match_flags = (U16)((RX_EXTFLAGS(re) & RXf_PMf_COMPILETIME)
192c1e27
JH
1022 >> RXf_PMf_STD_PMMOD_SHIFT);
1023
1024 while((ch = *fptr++)) {
1025 if(match_flags & 1) {
1026 reflags[left++] = ch;
1027 }
1028 match_flags >>= 1;
1029 }
1030
fb632ce3 1031 pattern = newSVpvn_flags(RX_PRECOMP(re),RX_PRELEN(re),
1604cfb0 1032 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
192c1e27
JH
1033
1034 /* return the pattern and the modifiers */
2102d7a2
S
1035 PUSHs(pattern);
1036 PUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
192c1e27
JH
1037 XSRETURN(2);
1038 } else {
1039 /* Scalar, so use the string that Perl would return */
33be4c61 1040 /* return the pattern in (?msixn:..) format */
daba3364 1041 pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
22d874e2 1042 PUSHs(pattern);
192c1e27
JH
1043 XSRETURN(1);
1044 }
1045 } else {
1046 /* It ain't a regexp folks */
eb7e169e 1047 if ( gimme == G_LIST ) {
192c1e27 1048 /* return the empty list */
7b46bf4c 1049 XSRETURN_EMPTY;
192c1e27
JH
1050 } else {
1051 /* Because of the (?:..) wrapping involved in a
1052 stringified pattern it is impossible to get a
1053 result for a real regexp that would evaluate to
1054 false. Therefore we can return PL_sv_no to signify
1055 that the object is not a regex, this means that one
1056 can say
1057
1058 if (regex($might_be_a_regex) eq '(?:foo)') { }
1059
1060 and not worry about undefined values.
1061 */
1062 XSRETURN_NO;
1063 }
1064 }
661d43c4 1065 NOT_REACHED; /* NOTREACHED */
192c1e27
JH
1066}
1067
15f67d14
TC
1068#ifdef HAS_GETCWD
1069
1070XS(XS_Internals_getcwd)
1071{
1072 dXSARGS;
1073 SV *sv = sv_newmortal();
1074
1075 if (items != 0)
1076 croak_xs_usage(cv, "");
1077
1078 (void)getcwd_sv(sv);
1079
1080 SvTAINTED_on(sv);
1081 PUSHs(sv);
1082 XSRETURN(1);
1083}
1084
1085#endif
1086
d88d17cb
TC
1087XS(XS_NamedCapture_tie_it)
1088{
1089 dXSARGS;
1090
1091 if (items != 1)
1092 croak_xs_usage(cv, "sv");
1093 {
1094 SV *sv = ST(0);
1095 GV * const gv = (GV *)sv;
1096 HV * const hv = GvHVn(gv);
1097 SV *rv = newSV_type(SVt_IV);
1098 const char *gv_name = GvNAME(gv);
1099
972c8f20 1100 sv_setrv_noinc(rv, newSVuv(
d88d17cb
TC
1101 strEQ(gv_name, "-") || strEQ(gv_name, "\003APTURE_ALL")
1102 ? RXapif_ALL : RXapif_ONE));
d88d17cb
TC
1103 sv_bless(rv, GvSTASH(CvGV(cv)));
1104
1105 sv_unmagic((SV *)hv, PERL_MAGIC_tied);
1106 sv_magic((SV *)hv, rv, PERL_MAGIC_tied, NULL, 0);
1107 SvREFCNT_dec(rv); /* As sv_magic increased it by one. */
1108 }
1109 XSRETURN_EMPTY;
1110}
1111
1112XS(XS_NamedCapture_TIEHASH)
1113{
c91f661c 1114 dXSARGS;
d88d17cb
TC
1115 if (items < 1)
1116 croak_xs_usage(cv, "package, ...");
1117 {
1604cfb0
MS
1118 const char * package = (const char *)SvPV_nolen(ST(0));
1119 UV flag = RXapif_ONE;
1120 mark += 2;
1121 while(mark < sp) {
1122 STRLEN len;
1123 const char *p = SvPV_const(*mark, len);
1124 if(memEQs(p, len, "all"))
1125 flag = SvTRUE(mark[1]) ? RXapif_ALL : RXapif_ONE;
1126 mark += 2;
1127 }
1128 ST(0) = sv_2mortal(newSV_type(SVt_IV));
1129 sv_setuv(newSVrv(ST(0), package), flag);
d88d17cb
TC
1130 }
1131 XSRETURN(1);
1132}
1133
1134/* These are tightly coupled to the RXapif_* flags defined in regexp.h */
1135#define UNDEF_FATAL 0x80000
1136#define DISCARD 0x40000
1137#define EXPECT_SHIFT 24
1138#define ACTION_MASK 0x000FF
1139
1140#define FETCH_ALIAS (RXapif_FETCH | (2 << EXPECT_SHIFT))
1141#define STORE_ALIAS (RXapif_STORE | (3 << EXPECT_SHIFT) | UNDEF_FATAL | DISCARD)
1142#define DELETE_ALIAS (RXapif_DELETE | (2 << EXPECT_SHIFT) | UNDEF_FATAL)
1143#define CLEAR_ALIAS (RXapif_CLEAR | (1 << EXPECT_SHIFT) | UNDEF_FATAL | DISCARD)
1144#define EXISTS_ALIAS (RXapif_EXISTS | (2 << EXPECT_SHIFT))
1145#define SCALAR_ALIAS (RXapif_SCALAR | (1 << EXPECT_SHIFT))
1146
1147XS(XS_NamedCapture_FETCH)
1148{
c91f661c 1149 dXSARGS;
d88d17cb
TC
1150 dXSI32;
1151 PERL_UNUSED_VAR(cv); /* -W */
1152 PERL_UNUSED_VAR(ax); /* -Wall */
1153 SP -= items;
1154 {
1604cfb0
MS
1155 REGEXP *const rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1156 U32 flags;
1157 SV *ret;
1158 const U32 action = ix & ACTION_MASK;
1159 const int expect = ix >> EXPECT_SHIFT;
1160 if (items != expect)
1161 croak_xs_usage(cv, expect == 2 ? "$key"
1162 : (expect == 3 ? "$key, $value"
1163 : ""));
1164
1165 if (!rx || !SvROK(ST(0))) {
1166 if (ix & UNDEF_FATAL)
1167 Perl_croak_no_modify();
1168 else
1169 XSRETURN_UNDEF;
1170 }
1171
1172 flags = (U32)SvUV(SvRV(MUTABLE_SV(ST(0))));
1173
1174 PUTBACK;
1175 ret = RX_ENGINE(rx)->named_buff(aTHX_ (rx), expect >= 2 ? ST(1) : NULL,
1176 expect >= 3 ? ST(2) : NULL, flags | action);
1177 SPAGAIN;
1178
1179 if (ix & DISCARD) {
1180 /* Called with G_DISCARD, so our return stack state is thrown away.
1181 Hence if we were returned anything, free it immediately. */
1182 SvREFCNT_dec(ret);
1183 } else {
1184 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
1185 }
1186 PUTBACK;
1187 return;
d88d17cb
TC
1188 }
1189}
1190
1191
1192XS(XS_NamedCapture_FIRSTKEY)
1193{
c91f661c 1194 dXSARGS;
d88d17cb
TC
1195 dXSI32;
1196 PERL_UNUSED_VAR(cv); /* -W */
1197 PERL_UNUSED_VAR(ax); /* -Wall */
1198 SP -= items;
1199 {
1604cfb0
MS
1200 REGEXP *const rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1201 U32 flags;
1202 SV *ret;
1203 const int expect = ix ? 2 : 1;
1204 const U32 action = ix ? RXapif_NEXTKEY : RXapif_FIRSTKEY;
1205 if (items != expect)
1206 croak_xs_usage(cv, expect == 2 ? "$lastkey" : "");
1207
1208 if (!rx || !SvROK(ST(0)))
1209 XSRETURN_UNDEF;
1210
1211 flags = (U32)SvUV(SvRV(MUTABLE_SV(ST(0))));
1212
1213 PUTBACK;
1214 ret = RX_ENGINE(rx)->named_buff_iter(aTHX_ (rx),
1215 expect >= 2 ? ST(1) : NULL,
1216 flags | action);
1217 SPAGAIN;
1218
1219 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
1220 PUTBACK;
1221 return;
d88d17cb
TC
1222 }
1223}
1224
1225/* is this still needed? */
1226XS(XS_NamedCapture_flags)
1227{
c91f661c 1228 dXSARGS;
d88d17cb
TC
1229 PERL_UNUSED_VAR(cv); /* -W */
1230 PERL_UNUSED_VAR(ax); /* -Wall */
1231 SP -= items;
1232 {
1604cfb0
MS
1233 EXTEND(SP, 2);
1234 mPUSHu(RXapif_ONE);
1235 mPUSHu(RXapif_ALL);
1236 PUTBACK;
1237 return;
d88d17cb
TC
1238 }
1239}
1240
b7a8ab8f 1241#include "vutil.h"
abc6d738
FC
1242#include "vxs.inc"
1243
eff5b9d5
NC
1244struct xsub_details {
1245 const char *name;
1246 XSUBADDR_t xsub;
1247 const char *proto;
d88d17cb 1248 int ix;
eff5b9d5
NC
1249};
1250
419f8ba5 1251static const struct xsub_details these_details[] = {
d88d17cb
TC
1252 {"UNIVERSAL::isa", XS_UNIVERSAL_isa, NULL, 0 },
1253 {"UNIVERSAL::can", XS_UNIVERSAL_can, NULL, 0 },
1254 {"UNIVERSAL::DOES", XS_UNIVERSAL_DOES, NULL, 0 },
abc6d738
FC
1255#define VXS_XSUB_DETAILS
1256#include "vxs.inc"
1257#undef VXS_XSUB_DETAILS
d88d17cb
TC
1258 {"utf8::is_utf8", XS_utf8_is_utf8, NULL, 0 },
1259 {"utf8::valid", XS_utf8_valid, NULL, 0 },
1260 {"utf8::encode", XS_utf8_encode, NULL, 0 },
1261 {"utf8::decode", XS_utf8_decode, NULL, 0 },
1262 {"utf8::upgrade", XS_utf8_upgrade, NULL, 0 },
1263 {"utf8::downgrade", XS_utf8_downgrade, NULL, 0 },
1264 {"utf8::native_to_unicode", XS_utf8_native_to_unicode, NULL, 0 },
1265 {"utf8::unicode_to_native", XS_utf8_unicode_to_native, NULL, 0 },
1266 {"Internals::SvREADONLY", XS_Internals_SvREADONLY, "\\[$%@];$", 0 },
1267 {"Internals::SvREFCNT", XS_Internals_SvREFCNT, "\\[$%@];$", 0 },
1268 {"Internals::hv_clear_placeholders", XS_Internals_hv_clear_placehold, "\\%", 0 },
1269 {"constant::_make_const", XS_constant__make_const, "\\[$@]", 0 },
1270 {"PerlIO::get_layers", XS_PerlIO_get_layers, "*;@", 0 },
1271 {"re::is_regexp", XS_re_is_regexp, "$", 0 },
1272 {"re::regname", XS_re_regname, ";$$", 0 },
1273 {"re::regnames", XS_re_regnames, ";$", 0 },
1274 {"re::regnames_count", XS_re_regnames_count, "", 0 },
1275 {"re::regexp_pattern", XS_re_regexp_pattern, "$", 0 },
15f67d14 1276#ifdef HAS_GETCWD
d88d17cb 1277 {"Internals::getcwd", XS_Internals_getcwd, "", 0 },
15f67d14 1278#endif
d88d17cb
TC
1279 {"Tie::Hash::NamedCapture::_tie_it", XS_NamedCapture_tie_it, NULL, 0 },
1280 {"Tie::Hash::NamedCapture::TIEHASH", XS_NamedCapture_TIEHASH, NULL, 0 },
1281 {"Tie::Hash::NamedCapture::FETCH", XS_NamedCapture_FETCH, NULL, FETCH_ALIAS },
1282 {"Tie::Hash::NamedCapture::STORE", XS_NamedCapture_FETCH, NULL, STORE_ALIAS },
1283 {"Tie::Hash::NamedCapture::DELETE", XS_NamedCapture_FETCH, NULL, DELETE_ALIAS },
1284 {"Tie::Hash::NamedCapture::CLEAR", XS_NamedCapture_FETCH, NULL, CLEAR_ALIAS },
1285 {"Tie::Hash::NamedCapture::EXISTS", XS_NamedCapture_FETCH, NULL, EXISTS_ALIAS },
1286 {"Tie::Hash::NamedCapture::SCALAR", XS_NamedCapture_FETCH, NULL, SCALAR_ALIAS },
1287 {"Tie::Hash::NamedCapture::FIRSTKEY", XS_NamedCapture_FIRSTKEY, NULL, 0 },
1288 {"Tie::Hash::NamedCapture::NEXTKEY", XS_NamedCapture_FIRSTKEY, NULL, 1 },
1289 {"Tie::Hash::NamedCapture::flags", XS_NamedCapture_flags, NULL, 0 },
eff5b9d5
NC
1290};
1291
273e254d
KW
1292STATIC OP*
1293optimize_out_native_convert_function(pTHX_ OP* entersubop,
1294 GV* namegv,
1295 SV* protosv)
1296{
1297 /* Optimizes out an identity function, i.e., one that just returns its
1298 * argument. The passed in function is assumed to be an identity function,
1299 * with no checking. This is designed to be called for utf8_to_native()
1300 * and native_to_utf8() on ASCII platforms, as they just return their
1301 * arguments, but it could work on any such function.
1302 *
1303 * The code is mostly just cargo-culted from Memoize::Lift */
1304
1305 OP *pushop, *argop;
614f287f 1306 OP *parent;
273e254d
KW
1307 SV* prototype = newSVpvs("$");
1308
1309 PERL_UNUSED_ARG(protosv);
1310
1311 assert(entersubop->op_type == OP_ENTERSUB);
1312
1313 entersubop = ck_entersub_args_proto(entersubop, namegv, prototype);
614f287f 1314 parent = entersubop;
273e254d
KW
1315
1316 SvREFCNT_dec(prototype);
1317
1318 pushop = cUNOPx(entersubop)->op_first;
bac7a184 1319 if (! OpHAS_SIBLING(pushop)) {
614f287f 1320 parent = pushop;
273e254d
KW
1321 pushop = cUNOPx(pushop)->op_first;
1322 }
614f287f 1323 argop = OpSIBLING(pushop);
273e254d
KW
1324
1325 /* Carry on without doing the optimization if it is not something we're
1326 * expecting, so continues to work */
1327 if ( ! argop
bac7a184 1328 || ! OpHAS_SIBLING(argop)
614f287f 1329 || OpHAS_SIBLING(OpSIBLING(argop))
273e254d
KW
1330 ) {
1331 return entersubop;
1332 }
1333
614f287f
DM
1334 /* cut argop from the subtree */
1335 (void)op_sibling_splice(parent, pushop, 1, NULL);
273e254d
KW
1336
1337 op_free(entersubop);
1338 return argop;
1339}
1340
eff5b9d5
NC
1341void
1342Perl_boot_core_UNIVERSAL(pTHX)
1343{
eff5b9d5 1344 static const char file[] = __FILE__;
419f8ba5
JK
1345 const struct xsub_details *xsub = these_details;
1346 const struct xsub_details *end = C_ARRAY_END(these_details);
eff5b9d5
NC
1347
1348 do {
d88d17cb
TC
1349 CV *cv = newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
1350 XSANY.any_i32 = xsub->ix;
eff5b9d5
NC
1351 } while (++xsub < end);
1352
273e254d
KW
1353#ifndef EBCDIC
1354 { /* On ASCII platforms these functions just return their argument, so can
1355 be optimized away */
1356
1357 CV* to_native_cv = get_cv("utf8::unicode_to_native", 0);
1358 CV* to_unicode_cv = get_cv("utf8::native_to_unicode", 0);
1359
a83b92fa 1360 cv_set_call_checker_flags(to_native_cv,
273e254d 1361 optimize_out_native_convert_function,
a83b92fa
Z
1362 (SV*) to_native_cv, 0);
1363 cv_set_call_checker_flags(to_unicode_cv,
273e254d 1364 optimize_out_native_convert_function,
a83b92fa 1365 (SV*) to_unicode_cv, 0);
273e254d
KW
1366 }
1367#endif
1368
eff5b9d5 1369 /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */
bad4ae38 1370 {
1604cfb0
MS
1371 CV * const cv =
1372 newCONSTSUB(get_hv("Regexp::", GV_ADD), "DESTROY", NULL);
1373 char ** cvfile = &CvFILE(cv);
1374 char * oldfile = *cvfile;
1375 CvDYNFILE_off(cv);
1376 *cvfile = (char *)file;
1377 Safefree(oldfile);
bad4ae38 1378 }
eff5b9d5 1379}
80305961 1380
241d1a3b 1381/*
14d04a33 1382 * ex: set ts=8 sts=4 sw=4 et:
37442d52 1383 */