3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 * 2005, 2006, 2007, 2008 by Larry Wall and others
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.
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
16 * [p.54 of _The Lord of the Rings_, I/ii: "The Shadow of the Past"]
19 /* This file contains the code that implements the functions in Perl's
20 * UNIVERSAL package, such as UNIVERSAL->can().
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 seperate XS files which would then be pulled
25 * in by some to-be-written build process.
29 #define PERL_IN_UNIVERSAL_C
33 #include "perliol.h" /* For the PERLIO_F_XXX */
37 S_get_isa_hash(pTHX_ HV *const stash)
40 struct mro_meta *const meta = HvMROMETA(stash);
42 PERL_ARGS_ASSERT_GET_ISA_HASH;
45 (void)mro_get_linear_isa(stash);
51 * Contributed by Graham Barr <Graham.Barr@tiuk.ti.com>
52 * The main guts of traverse_isa was actually copied from gv_fetchmeth
56 S_isa_lookup(pTHX_ HV *stash, const char * const name)
59 const struct mro_meta *const meta = HvMROMETA(stash);
60 HV *const isa = meta->isa ? meta->isa : S_get_isa_hash(aTHX_ stash);
61 STRLEN len = strlen(name);
64 PERL_ARGS_ASSERT_ISA_LOOKUP;
66 if (hv_common(isa, NULL, name, len, 0 /* No "UTF-8" flag possible with only
68 HV_FETCH_ISEXISTS, NULL, 0)) {
69 /* Direct name lookup worked. */
73 /* A stash/class can go by many names (ie. User == main::User), so
74 we use the HvENAME in the stash itself, which is canonical, falling
75 back to HvNAME if necessary. */
76 our_stash = gv_stashpvn(name, len, 0);
79 HEK *canon_name = HvENAME_HEK(our_stash);
80 if (!canon_name) canon_name = HvNAME_HEK(our_stash);
82 if (hv_common(isa, NULL, HEK_KEY(canon_name), HEK_LEN(canon_name),
83 HEK_FLAGS(canon_name),
84 HV_FETCH_ISEXISTS, NULL, HEK_HASH(canon_name))) {
93 =head1 SV Manipulation Functions
95 =for apidoc sv_derived_from
97 Returns a boolean indicating whether the SV is derived from the specified class
98 I<at the C level>. To check derivation at the Perl level, call C<isa()> as a
105 Perl_sv_derived_from(pTHX_ SV *sv, const char *const name)
110 PERL_ARGS_ASSERT_SV_DERIVED_FROM;
117 type = sv_reftype(sv,0);
118 if (type && strEQ(type,name))
120 stash = SvOBJECT(sv) ? SvSTASH(sv) : NULL;
123 stash = gv_stashsv(sv, 0);
126 return stash ? isa_lookup(stash, name) : FALSE;
132 Returns a boolean indicating whether the SV performs a specific, named role.
133 The SV can be a Perl object or the name of a Perl class.
141 Perl_sv_does(pTHX_ SV *sv, const char *const name)
143 const char *classname;
148 PERL_ARGS_ASSERT_SV_DOES;
155 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
156 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv)))) {
161 if (sv_isobject(sv)) {
162 classname = sv_reftype(SvRV(sv),TRUE);
164 classname = SvPV_nolen(sv);
167 if (strEQ(name,classname)) {
174 mXPUSHs(newSVpv(name, 0));
177 methodname = newSVpvs_flags("isa", SVs_TEMP);
178 /* ugly hack: use the SvSCREAM flag so S_method_common
179 * can figure out we're calling DOES() and not isa(),
180 * and report eventual errors correctly. --rgs */
181 SvSCREAM_on(methodname);
182 call_sv(methodname, G_SCALAR | G_METHOD);
185 does_it = SvTRUE( TOPs );
193 =for apidoc croak_xs_usage
195 A specialised variant of C<croak()> for emitting the usage message for xsubs
197 croak_xs_usage(cv, "eee_yow");
199 works out the package name and subroutine name from C<cv>, and then calls
200 C<croak()>. Hence if C<cv> is C<&ouch::awk>, it would call C<croak> as:
202 Perl_croak(aTHX_ "Usage: %s::%s(%s)", "ouch" "awk", "eee_yow");
208 Perl_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
210 const GV *const gv = CvGV(cv);
212 PERL_ARGS_ASSERT_CROAK_XS_USAGE;
215 const char *const gvname = GvNAME(gv);
216 const HV *const stash = GvSTASH(gv);
217 const char *const hvname = stash ? HvNAME_get(stash) : NULL;
220 Perl_croak(aTHX_ "Usage: %s::%s(%s)", hvname, gvname, params);
222 Perl_croak(aTHX_ "Usage: %s(%s)", gvname, params);
224 /* Pants. I don't think that it should be possible to get here. */
225 Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
235 croak_xs_usage(cv, "reference, kind");
237 SV * const sv = ST(0);
242 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
243 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
246 name = SvPV_nolen_const(ST(1));
248 ST(0) = boolSV(sv_derived_from(sv, name));
263 croak_xs_usage(cv, "object-ref, method");
269 if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
270 || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
273 name = SvPV_nolen_const(ST(1));
277 sv = MUTABLE_SV(SvRV(sv));
282 pkg = gv_stashsv(sv, 0);
286 GV * const gv = gv_fetchmethod_autoload(pkg, name, FALSE);
288 rv = sv_2mortal(newRV(MUTABLE_SV(GvCV(gv))));
295 XS(XS_UNIVERSAL_DOES)
302 Perl_croak(aTHX_ "Usage: invocant->DOES(kind)");
304 SV * const sv = ST(0);
307 name = SvPV_nolen_const(ST(1));
308 if (sv_does( sv, name ))
315 XS(XS_UNIVERSAL_VERSION)
327 sv = MUTABLE_SV(SvRV(ST(0)));
329 Perl_croak(aTHX_ "Cannot find version of an unblessed reference");
333 pkg = gv_stashsv(ST(0), 0);
336 gvp = pkg ? (GV**)hv_fetchs(pkg, "VERSION", FALSE) : NULL;
338 if (gvp && isGV(gv = *gvp) && (sv = GvSV(gv)) && SvOK(sv)) {
339 SV * const nsv = sv_newmortal();
342 if ( !sv_derived_from(sv, "version"))
343 upg_version(sv, FALSE);
356 const char * const name = HvNAME_get(pkg);
358 "%s does not define $%s::VERSION--version check failed",
362 "%s defines neither package nor VERSION--version check failed",
363 SvPVx_nolen_const(ST(0)) );
367 if ( !sv_derived_from(req, "version")) {
368 /* req may very well be R/O, so create a new object */
369 req = sv_2mortal( new_version(req) );
372 if ( vcmp( req, sv ) > 0 ) {
373 if ( hv_exists(MUTABLE_HV(SvRV(req)), "qv", 2 ) ) {
374 Perl_croak(aTHX_ "%s version %"SVf" required--"
375 "this is only version %"SVf"", HvNAME_get(pkg),
376 SVfARG(sv_2mortal(vnormal(req))),
377 SVfARG(sv_2mortal(vnormal(sv))));
379 Perl_croak(aTHX_ "%s version %"SVf" required--"
380 "this is only version %"SVf"", HvNAME_get(pkg),
381 SVfARG(sv_2mortal(vstringify(req))),
382 SVfARG(sv_2mortal(vstringify(sv))));
388 if ( SvOK(sv) && sv_derived_from(sv, "version") ) {
389 ST(0) = sv_2mortal(vstringify(sv));
402 croak_xs_usage(cv, "class, version");
407 const char * const classname =
408 sv_isobject(ST(0)) /* get the class if called as an object method */
409 ? HvNAME(SvSTASH(SvRV(ST(0))))
410 : (char *)SvPV_nolen(ST(0));
412 if ( items == 1 || ! SvOK(vs) ) { /* no param or explicit undef */
413 /* create empty object */
417 else if ( items == 3 ) {
419 Perl_sv_setpvf(aTHX_ vs,"v%s",SvPV_nolen_const(ST(2)));
422 rv = new_version(vs);
423 if ( strcmp(classname,"version") != 0 ) /* inherited new() */
424 sv_bless(rv, gv_stashpv(classname, GV_ADD));
432 XS(XS_version_stringify)
437 croak_xs_usage(cv, "lobj, ...");
442 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
446 Perl_croak(aTHX_ "lobj is not of type version");
448 mPUSHs(vstringify(lobj));
455 XS(XS_version_numify)
460 croak_xs_usage(cv, "lobj, ...");
465 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
469 Perl_croak(aTHX_ "lobj is not of type version");
471 mPUSHs(vnumify(lobj));
478 XS(XS_version_normal)
483 croak_xs_usage(cv, "lobj, ...");
488 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
492 Perl_croak(aTHX_ "lobj is not of type version");
494 mPUSHs(vnormal(lobj));
506 croak_xs_usage(cv, "lobj, ...");
511 if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
515 Perl_croak(aTHX_ "lobj is not of type version");
521 const IV swap = (IV)SvIV(ST(2));
523 if ( ! sv_derived_from(robj, "version") )
525 robj = new_version(SvOK(robj) ? robj : newSVpvs_flags("0", SVs_TEMP));
532 rs = newSViv(vcmp(rvs,lobj));
536 rs = newSViv(vcmp(lobj,rvs));
547 XS(XS_version_boolean)
552 croak_xs_usage(cv, "lobj, ...");
554 if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
555 SV * const lobj = SvRV(ST(0));
556 SV * const rs = newSViv( vcmp(lobj,new_version(newSVpvs("0"))) );
562 Perl_croak(aTHX_ "lobj is not of type version");
570 croak_xs_usage(cv, "lobj, ...");
571 if (sv_derived_from(ST(0), "version") && SvROK(ST(0)))
572 Perl_croak(aTHX_ "operation not supported with version object");
574 Perl_croak(aTHX_ "lobj is not of type version");
575 #ifndef HASATTRIBUTE_NORETURN
580 XS(XS_version_is_alpha)
585 croak_xs_usage(cv, "lobj");
587 if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
588 SV * const lobj = ST(0);
589 if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "alpha", 5 ) )
597 Perl_croak(aTHX_ "lobj is not of type version");
609 const char * classname = "";
610 if ( items == 2 && SvOK(ST(1)) ) {
611 /* getting called as object or class method */
614 sv_isobject(ST(0)) /* class called as an object method */
615 ? HvNAME_get(SvSTASH(SvRV(ST(0))))
616 : (char *)SvPV_nolen(ST(0));
618 if ( !SvVOK(ver) ) { /* not already a v-string */
620 sv_setsv(rv,ver); /* make a duplicate */
621 upg_version(rv, TRUE);
623 rv = sv_2mortal(new_version(ver));
625 if ( items == 2 && strcmp(classname,"version") ) { /* inherited new() */
626 sv_bless(rv, gv_stashpv(classname, GV_ADD));
639 croak_xs_usage(cv, "lobj");
641 if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
642 SV * const lobj = ST(0);
643 if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "qv", 2 ) )
651 Perl_croak(aTHX_ "lobj is not of type version");
659 croak_xs_usage(cv, "sv");
661 SV * const sv = ST(0);
676 croak_xs_usage(cv, "sv");
678 SV * const sv = ST(0);
680 const char * const s = SvPV_const(sv,len);
681 if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len))
694 croak_xs_usage(cv, "sv");
695 sv_utf8_encode(ST(0));
704 croak_xs_usage(cv, "sv");
706 SV * const sv = ST(0);
707 const bool RETVAL = sv_utf8_decode(sv);
708 ST(0) = boolSV(RETVAL);
719 croak_xs_usage(cv, "sv");
721 SV * const sv = ST(0);
725 RETVAL = sv_utf8_upgrade(sv);
726 XSprePUSH; PUSHi((IV)RETVAL);
731 XS(XS_utf8_downgrade)
735 if (items < 1 || items > 2)
736 croak_xs_usage(cv, "sv, failok=0");
738 SV * const sv = ST(0);
739 const bool failok = (items < 2) ? 0 : (int)SvIV(ST(1));
740 const bool RETVAL = sv_utf8_downgrade(sv, failok);
742 ST(0) = boolSV(RETVAL);
748 XS(XS_utf8_native_to_unicode)
752 const UV uv = SvUV(ST(0));
755 croak_xs_usage(cv, "sv");
757 ST(0) = sv_2mortal(newSViv(NATIVE_TO_UNI(uv)));
761 XS(XS_utf8_unicode_to_native)
765 const UV uv = SvUV(ST(0));
768 croak_xs_usage(cv, "sv");
770 ST(0) = sv_2mortal(newSViv(UNI_TO_NATIVE(uv)));
774 XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */
778 SV * const svz = ST(0);
782 /* [perl #77776] - called as &foo() not foo() */
784 croak_xs_usage(cv, "SCALAR[, ON]");
794 else if (items == 2) {
800 /* I hope you really know what you are doing. */
805 XSRETURN_UNDEF; /* Can't happen. */
808 XS(XS_Internals_SvREFCNT) /* This is dangerous stuff. */
812 SV * const svz = ST(0);
816 /* [perl #77776] - called as &foo() not foo() */
818 croak_xs_usage(cv, "SCALAR[, REFCOUNT]");
823 XSRETURN_IV(SvREFCNT(sv) - 1); /* Minus the ref created for us. */
824 else if (items == 2) {
825 /* I hope you really know what you are doing. */
826 SvREFCNT(sv) = SvIV(ST(1));
827 XSRETURN_IV(SvREFCNT(sv));
829 XSRETURN_UNDEF; /* Can't happen. */
832 XS(XS_Internals_hv_clear_placehold)
837 if (items != 1 || !SvROK(ST(0)))
838 croak_xs_usage(cv, "hv");
840 HV * const hv = MUTABLE_HV(SvRV(ST(0)));
841 hv_clear_placeholders(hv);
846 XS(XS_PerlIO_get_layers)
850 if (items < 1 || items % 2 == 0)
851 croak_xs_usage(cv, "filehandle[,args]");
858 bool details = FALSE;
862 for (svp = MARK + 2; svp <= SP; svp += 2) {
863 SV * const * const varp = svp;
864 SV * const * const valp = svp + 1;
866 const char * const key = SvPV_const(*varp, klen);
870 if (klen == 5 && memEQ(key, "input", 5)) {
871 input = SvTRUE(*valp);
876 if (klen == 6 && memEQ(key, "output", 6)) {
877 input = !SvTRUE(*valp);
882 if (klen == 7 && memEQ(key, "details", 7)) {
883 details = SvTRUE(*valp);
890 "get_layers: unknown argument '%s'",
902 if (SvROK(sv) && isGV(SvRV(sv)))
903 gv = MUTABLE_GV(SvRV(sv));
905 gv = gv_fetchsv(sv, 0, SVt_PVIO);
908 if (gv && (io = GvIO(gv))) {
909 AV* const av = PerlIO_get_layers(aTHX_ input ?
910 IoIFP(io) : IoOFP(io));
912 const I32 last = av_len(av);
915 for (i = last; i >= 0; i -= 3) {
916 SV * const * const namsvp = av_fetch(av, i - 2, FALSE);
917 SV * const * const argsvp = av_fetch(av, i - 1, FALSE);
918 SV * const * const flgsvp = av_fetch(av, i, FALSE);
920 const bool namok = namsvp && *namsvp && SvPOK(*namsvp);
921 const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
922 const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
925 /* Indents of 5? Yuck. */
926 /* We know that PerlIO_get_layers creates a new SV for
927 the name and flags, so we can just take a reference
928 and "steal" it when we free the AV below. */
930 ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
933 ? newSVpvn_flags(SvPVX_const(*argsvp),
935 (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
939 ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
945 XPUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
949 XPUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
951 XPUSHs(&PL_sv_undef);
954 const IV flags = SvIVX(*flgsvp);
956 if (flags & PERLIO_F_UTF8) {
957 XPUSHs(newSVpvs_flags("utf8", SVs_TEMP));
974 XS(XS_Internals_hash_seed)
977 /* Using dXSARGS would also have dITEM and dSP,
978 * which define 2 unused local variables. */
981 PERL_UNUSED_VAR(mark);
982 XSRETURN_UV(PERL_HASH_SEED);
985 XS(XS_Internals_rehash_seed)
988 /* Using dXSARGS would also have dITEM and dSP,
989 * which define 2 unused local variables. */
992 PERL_UNUSED_VAR(mark);
993 XSRETURN_UV(PL_rehash_seed);
996 XS(XS_Internals_HvREHASH) /* Subject to change */
1000 PERL_UNUSED_ARG(cv);
1002 const HV * const hv = (const HV *) SvRV(ST(0));
1003 if (items == 1 && SvTYPE(hv) == SVt_PVHV) {
1010 Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
1017 PERL_UNUSED_VAR(cv);
1020 croak_xs_usage(cv, "sv");
1022 if (SvRXOK(ST(0))) {
1029 XS(XS_re_regnames_count)
1031 REGEXP *rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1037 croak_xs_usage(cv, "");
1045 ret = CALLREG_NAMED_BUFF_COUNT(rx);
1048 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
1060 if (items < 1 || items > 2)
1061 croak_xs_usage(cv, "name[, all ]");
1066 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1071 if (items == 2 && SvTRUE(ST(1))) {
1076 ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(0), (flags | RXapif_REGNAME));
1079 PUSHs(ret ? sv_2mortal(ret) : &PL_sv_undef);
1097 croak_xs_usage(cv, "[all]");
1099 rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
1104 if (items == 1 && SvTRUE(ST(0))) {
1113 ret = CALLREG_NAMED_BUFF_ALL(rx, (flags | RXapif_REGNAMES));
1120 av = MUTABLE_AV(SvRV(ret));
1121 length = av_len(av);
1123 for (i = 0; i <= length; i++) {
1124 entry = av_fetch(av, i, FALSE);
1127 Perl_croak(aTHX_ "NULL array element in re::regnames()");
1129 mXPUSHs(SvREFCNT_inc_simple_NN(*entry));
1138 XS(XS_re_regexp_pattern)
1145 croak_xs_usage(cv, "sv");
1150 Checks if a reference is a regex or not. If the parameter is
1151 not a ref, or is not the result of a qr// then returns false
1152 in scalar context and an empty list in list context.
1153 Otherwise in list context it returns the pattern and the
1154 modifiers, in scalar context it returns the pattern just as it
1155 would if the qr// was stringified normally, regardless as
1156 to the class of the variable and any strigification overloads
1160 if ((re = SvRX(ST(0)))) /* assign deliberate */
1162 /* Houston, we have a regex! */
1165 if ( GIMME_V == G_ARRAY ) {
1167 char reflags[sizeof(INT_PAT_MODS) + 1]; /* The +1 is for the charset
1174 we are in list context so stringify
1175 the modifiers that apply. We ignore "negative
1176 modifiers" in this scenario.
1179 if (RX_EXTFLAGS(re) & RXf_PMf_LOCALE) {
1180 reflags[left++] = LOCALE_PAT_MOD;
1182 else if (RX_EXTFLAGS(re) & RXf_PMf_UNICODE) {
1183 reflags[left++] = UNICODE_PAT_MOD;
1185 fptr = INT_PAT_MODS;
1186 match_flags = (U16)((RX_EXTFLAGS(re) & PMf_COMPILETIME)
1187 >> RXf_PMf_STD_PMMOD_SHIFT);
1189 while((ch = *fptr++)) {
1190 if(match_flags & 1) {
1191 reflags[left++] = ch;
1196 pattern = newSVpvn_flags(RX_PRECOMP(re),RX_PRELEN(re),
1197 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
1199 /* return the pattern and the modifiers */
1201 XPUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
1204 /* Scalar, so use the string that Perl would return */
1205 /* return the pattern in (?msix:..) format */
1206 #if PERL_VERSION >= 11
1207 pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
1209 pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
1210 (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
1216 /* It ain't a regexp folks */
1217 if ( GIMME_V == G_ARRAY ) {
1218 /* return the empty list */
1221 /* Because of the (?:..) wrapping involved in a
1222 stringified pattern it is impossible to get a
1223 result for a real regexp that would evaluate to
1224 false. Therefore we can return PL_sv_no to signify
1225 that the object is not a regex, this means that one
1228 if (regex($might_be_a_regex) eq '(?:foo)') { }
1230 and not worry about undefined values.
1238 struct xsub_details {
1244 struct xsub_details details[] = {
1245 {"UNIVERSAL::isa", XS_UNIVERSAL_isa, NULL},
1246 {"UNIVERSAL::can", XS_UNIVERSAL_can, NULL},
1247 {"UNIVERSAL::DOES", XS_UNIVERSAL_DOES, NULL},
1248 {"UNIVERSAL::VERSION", XS_UNIVERSAL_VERSION, NULL},
1249 {"version::()", XS_version_noop, NULL},
1250 {"version::new", XS_version_new, NULL},
1251 {"version::parse", XS_version_new, NULL},
1252 {"version::(\"\"", XS_version_stringify, NULL},
1253 {"version::stringify", XS_version_stringify, NULL},
1254 {"version::(0+", XS_version_numify, NULL},
1255 {"version::numify", XS_version_numify, NULL},
1256 {"version::normal", XS_version_normal, NULL},
1257 {"version::(cmp", XS_version_vcmp, NULL},
1258 {"version::(<=>", XS_version_vcmp, NULL},
1259 {"version::vcmp", XS_version_vcmp, NULL},
1260 {"version::(bool", XS_version_boolean, NULL},
1261 {"version::boolean", XS_version_boolean, NULL},
1262 {"version::(nomethod", XS_version_noop, NULL},
1263 {"version::noop", XS_version_noop, NULL},
1264 {"version::is_alpha", XS_version_is_alpha, NULL},
1265 {"version::qv", XS_version_qv, NULL},
1266 {"version::declare", XS_version_qv, NULL},
1267 {"version::is_qv", XS_version_is_qv, NULL},
1268 {"utf8::is_utf8", XS_utf8_is_utf8, NULL},
1269 {"utf8::valid", XS_utf8_valid, NULL},
1270 {"utf8::encode", XS_utf8_encode, NULL},
1271 {"utf8::decode", XS_utf8_decode, NULL},
1272 {"utf8::upgrade", XS_utf8_upgrade, NULL},
1273 {"utf8::downgrade", XS_utf8_downgrade, NULL},
1274 {"utf8::native_to_unicode", XS_utf8_native_to_unicode, NULL},
1275 {"utf8::unicode_to_native", XS_utf8_unicode_to_native, NULL},
1276 {"Internals::SvREADONLY", XS_Internals_SvREADONLY, "\\[$%@];$"},
1277 {"Internals::SvREFCNT", XS_Internals_SvREFCNT, "\\[$%@];$"},
1278 {"Internals::hv_clear_placeholders", XS_Internals_hv_clear_placehold, "\\%"},
1279 {"PerlIO::get_layers", XS_PerlIO_get_layers, "*;@"},
1280 {"Internals::hash_seed", XS_Internals_hash_seed, ""},
1281 {"Internals::rehash_seed", XS_Internals_rehash_seed, ""},
1282 {"Internals::HvREHASH", XS_Internals_HvREHASH, "\\%"},
1283 {"re::is_regexp", XS_re_is_regexp, "$"},
1284 {"re::regname", XS_re_regname, ";$$"},
1285 {"re::regnames", XS_re_regnames, ";$"},
1286 {"re::regnames_count", XS_re_regnames_count, ""},
1287 {"re::regexp_pattern", XS_re_regexp_pattern, "$"},
1291 Perl_boot_core_UNIVERSAL(pTHX)
1294 static const char file[] = __FILE__;
1295 struct xsub_details *xsub = details;
1296 const struct xsub_details *end
1297 = details + sizeof(details) / sizeof(details[0]);
1300 newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
1301 } while (++xsub < end);
1303 /* register the overloading (type 'A') magic */
1304 PL_amagic_generation++;
1306 /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */
1307 CvFILE(newCONSTSUB(get_hv("Regexp::", GV_ADD), "DESTROY", NULL))
1313 * c-indentation-style: bsd
1315 * indent-tabs-mode: t
1318 * ex: set ts=8 sts=4 sw=4 noet: