* The main guts of traverse_isa was actually copied from gv_fetchmeth
*/
+#define PERL_ARGS_ASSERT_ISA_LOOKUP \
+ assert(stash); \
+ assert(namesv || name)
+
+
STATIC bool
-S_isa_lookup(pTHX_ HV *stash, const char * const name, STRLEN len, U32 flags)
+S_isa_lookup(pTHX_ HV *stash, SV *namesv, const char * name, STRLEN len, U32 flags)
{
const struct mro_meta *const meta = HvMROMETA(stash);
HV *isa = meta->isa;
isa = meta->isa;
}
- if (hv_common(isa, NULL, name, len, ( flags & SVf_UTF8 ? HVhek_UTF8 : 0),
+ if (hv_common(isa, namesv, name, len, ( flags & SVf_UTF8 ? HVhek_UTF8 : 0),
HV_FETCH_ISEXISTS, NULL, 0)) {
/* Direct name lookup worked. */
return TRUE;
/* A stash/class can go by many names (ie. User == main::User), so
we use the HvENAME in the stash itself, which is canonical, falling
back to HvNAME if necessary. */
- our_stash = gv_stashpvn(name, len, flags);
+ our_stash = gv_stashsvpvn_cached(namesv, name, len, flags);
if (our_stash) {
HEK *canon_name = HvENAME_HEK(our_stash);
return FALSE;
}
+#define PERL_ARGS_ASSERT_SV_DERIVED_FROM_SVPVN \
+ assert(sv); \
+ assert(namesv || name)
+
+STATIC bool
+S_sv_derived_from_svpvn(pTHX_ SV *sv, SV *namesv, const char * name, const STRLEN len, U32 flags)
+{
+ HV* stash;
+
+ PERL_ARGS_ASSERT_SV_DERIVED_FROM_SVPVN;
+ SvGETMAGIC(sv);
+
+ if (SvROK(sv)) {
+ const char *type;
+ sv = SvRV(sv);
+ type = sv_reftype(sv,0);
+ if (type) {
+ if (namesv)
+ name = SvPV_nolen(namesv);
+ if (strEQ(name, type))
+ return TRUE;
+ }
+ if (!SvOBJECT(sv))
+ return FALSE;
+ stash = SvSTASH(sv);
+ }
+ else {
+ stash = gv_stashsv(sv, 0);
+ }
+
+ if (stash && isa_lookup(stash, namesv, name, len, flags))
+ return TRUE;
+
+ stash = gv_stashpvs("UNIVERSAL", 0);
+ return stash && isa_lookup(stash, namesv, name, len, flags);
+}
+
/*
=head1 SV Manipulation Functions
=for apidoc sv_derived_from_sv
Exactly like L</sv_derived_from_pvn>, but takes the name string in the form
-of an SV instead of a string/length pair.
+of an SV instead of a string/length pair. This is the advised form.
=cut
bool
Perl_sv_derived_from_sv(pTHX_ SV *sv, SV *namesv, U32 flags)
{
- char *namepv;
- STRLEN namelen;
PERL_ARGS_ASSERT_SV_DERIVED_FROM_SV;
- namepv = SvPV(namesv, namelen);
- if (SvUTF8(namesv))
- flags |= SVf_UTF8;
- return sv_derived_from_pvn(sv, namepv, namelen, flags);
+ return sv_derived_from_svpvn(sv, namesv, NULL, 0, flags);
}
/*
Perl_sv_derived_from(pTHX_ SV *sv, const char *const name)
{
PERL_ARGS_ASSERT_SV_DERIVED_FROM;
- return sv_derived_from_pvn(sv, name, strlen(name), 0);
+ return sv_derived_from_svpvn(sv, NULL, name, strlen(name), 0);
}
/*
Perl_sv_derived_from_pv(pTHX_ SV *sv, const char *const name, U32 flags)
{
PERL_ARGS_ASSERT_SV_DERIVED_FROM_PV;
- return sv_derived_from_pvn(sv, name, strlen(name), flags);
+ return sv_derived_from_svpvn(sv, NULL, name, strlen(name), flags);
}
bool
Perl_sv_derived_from_pvn(pTHX_ SV *sv, const char *const name, const STRLEN len, U32 flags)
{
- HV *stash;
-
PERL_ARGS_ASSERT_SV_DERIVED_FROM_PVN;
-
- SvGETMAGIC(sv);
-
- if (SvROK(sv)) {
- const char *type;
- sv = SvRV(sv);
- type = sv_reftype(sv,0);
- if (type && strEQ(type,name))
- return TRUE;
- if (!SvOBJECT(sv))
- return FALSE;
- stash = SvSTASH(sv);
- }
- else {
- stash = gv_stashsv(sv, 0);
- }
-
- if (stash && isa_lookup(stash, name, len, flags))
- return TRUE;
-
- stash = gv_stashpvs("UNIVERSAL", 0);
- return stash && isa_lookup(stash, name, len, flags);
+ return sv_derived_from_svpvn(sv, NULL, name, len, flags);
}
/*
PUSHs(namesv);
PUTBACK;
- methodname = newSVpvs_flags("isa", SVs_TEMP);
- /* ugly hack: use the SvSCREAM flag so S_method_common
- * can figure out we're calling DOES() and not isa(),
- * and report eventual errors correctly. --rgs */
- SvSCREAM_on(methodname);
+ /* create a PV with value "isa", but with a special address
+ * so that perl knows we're really doing "DOES" instead */
+ methodname = newSV_type(SVt_PV);
+ SvLEN_set(methodname, 0);
+ SvCUR_set(methodname, strlen(PL_isa_DOES));
+ SvPVX(methodname) = (char *)PL_isa_DOES; /* discard 'const' qualifier */
+ SvPOK_on(methodname);
+ sv_2mortal(methodname);
call_sv(methodname, G_SCALAR | G_METHOD);
SPAGAIN;
- does_it = SvTRUE( TOPs );
+ does_it = SvTRUE_NN( TOPs );
FREETMPS;
LEAVE;
works out the package name and subroutine name from C<cv>, and then calls
C<croak()>. Hence if C<cv> is C<&ouch::awk>, it would call C<croak> as:
- Perl_croak(aTHX_ "Usage: %"SVf"::%"SVf"(%s)", "ouch" "awk",
+ Perl_croak(aTHX_ "Usage: %" SVf "::%" SVf "(%s)", "ouch" "awk",
"eee_yow");
=cut
if (HvNAME_get(stash))
/* diag_listed_as: SKIPME */
- Perl_croak_nocontext("Usage: %"HEKf"::%"HEKf"(%s)",
+ Perl_croak_nocontext("Usage: %" HEKf "::%" HEKf "(%s)",
HEKfARG(HvNAME_HEK(stash)),
HEKfARG(GvNAME_HEK(gv)),
params);
else
/* diag_listed_as: SKIPME */
- Perl_croak_nocontext("Usage: %"HEKf"(%s)",
+ Perl_croak_nocontext("Usage: %" HEKf "(%s)",
HEKfARG(GvNAME_HEK(gv)), params);
} else {
dTHX;
/* Pants. I don't think that it should be possible to get here. */
/* diag_listed_as: SKIPME */
- Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
+ Perl_croak(aTHX_ "Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
}
}
if (items < 1 || items > 2)
croak_xs_usage(cv, "sv, failok=0");
else {
- SV * const sv = ST(0);
- const bool failok = (items < 2) ? 0 : SvTRUE(ST(1)) ? 1 : 0;
- const bool RETVAL = sv_utf8_downgrade(sv, failok);
+ SV * const sv0 = ST(0);
+ SV * const sv1 = ST(1);
+ const bool failok = (items < 2) ? 0 : SvTRUE_NN(sv1) ? 1 : 0;
+ const bool RETVAL = sv_utf8_downgrade(sv0, failok);
ST(0) = boolSV(RETVAL);
}
dXSARGS;
SV * const svz = ST(0);
SV * sv;
- PERL_UNUSED_ARG(cv);
/* [perl #77776] - called as &foo() not foo() */
if (!SvROK(svz))
XSRETURN_NO;
}
else if (items == 2) {
- if (SvTRUE(ST(1))) {
+ SV *sv1 = ST(1);
+ if (SvTRUE_NN(sv1)) {
SvFLAGS(sv) |= SVf_READONLY;
XSRETURN_YES;
}
dXSARGS;
SV * const svz = ST(0);
SV * sv;
- PERL_UNUSED_ARG(cv);
/* [perl #77776] - called as &foo() not foo() */
if (!SvROK(svz) || items != 1)
SV * const svz = ST(0);
SV * sv;
U32 refcnt;
- PERL_UNUSED_ARG(cv);
/* [perl #77776] - called as &foo() not foo() */
if ((items != 1 && items != 2) || !SvROK(svz))
}
+XS(XS_Internals_hv_clear_placehold); /* prototype to pass -Wmissing-prototypes */
+XS(XS_Internals_hv_clear_placehold)
+{
+ dXSARGS;
+
+ if (items != 1 || !SvROK(ST(0)))
+ croak_xs_usage(cv, "hv");
+ else {
+ HV * const hv = MUTABLE_HV(SvRV(ST(0)));
+ hv_clear_placeholders(hv);
+ XSRETURN(0);
+ }
+}
+
XS(XS_PerlIO_get_layers); /* prototype to pass -Wmissing-prototypes */
XS(XS_PerlIO_get_layers)
{
switch (*key) {
case 'i':
- if (klen == 5 && memEQ(key, "input", 5)) {
+ if (memEQs(key, klen, "input")) {
input = SvTRUE(*valp);
break;
}
goto fail;
case 'o':
- if (klen == 6 && memEQ(key, "output", 6)) {
+ if (memEQs(key, klen, "output")) {
input = !SvTRUE(*valp);
break;
}
goto fail;
case 'd':
- if (klen == 7 && memEQ(key, "details", 7)) {
+ if (memEQs(key, klen, "details")) {
details = SvTRUE(*valp);
break;
}
}
else {
if (namok && argok)
- PUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
+ PUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%" SVf "(%" SVf ")",
SVfARG(*namsvp),
SVfARG(*argsvp))));
else if (namok)
XSRETURN(0);
}
-XS(XS_hash_util_bucket_ratio); /* prototype to pass -Wmissing-prototypes */
-XS(XS_hash_util_bucket_ratio)
-{
- dXSARGS;
- SV *rhv;
- PERL_UNUSED_VAR(cv);
-
- if (items != 1)
- croak_xs_usage(cv, "hv");
-
- rhv= ST(0);
- if (SvROK(rhv)) {
- rhv= SvRV(rhv);
- if ( SvTYPE(rhv)==SVt_PVHV ) {
- SV *ret= Perl_hv_bucket_ratio(aTHX_ (HV*)rhv);
- ST(0)= ret;
- XSRETURN(1);
- }
- }
- XSRETURN_UNDEF;
-}
-
-XS(XS_hash_util_num_buckets); /* prototype to pass -Wmissing-prototypes */
-XS(XS_hash_util_num_buckets)
-{
- dXSARGS;
- SV *rhv;
- PERL_UNUSED_VAR(cv);
-
- if (items != 1)
- croak_xs_usage(cv, "hv");
-
- rhv= ST(0);
- if (SvROK(rhv)) {
- rhv= SvRV(rhv);
- if ( SvTYPE(rhv)==SVt_PVHV ) {
- XSRETURN_UV(HvMAX((HV*)rhv)+1);
- }
- }
- XSRETURN_UNDEF;
-}
-
-XS(XS_hash_util_used_buckets); /* prototype to pass -Wmissing-prototypes */
-XS(XS_hash_util_used_buckets)
-{
- dXSARGS;
- SV *rhv;
- PERL_UNUSED_VAR(cv);
-
- if (items != 1)
- croak_xs_usage(cv, "hv");
-
- rhv= ST(0);
- if (SvROK(rhv)) {
- rhv= SvRV(rhv);
- if ( SvTYPE(rhv)==SVt_PVHV ) {
- XSRETURN_UV(HvFILL((HV*)rhv));
- }
- }
- XSRETURN_UNDEF;
-}
-
XS(XS_re_is_regexp); /* prototype to pass -Wmissing-prototypes */
XS(XS_re_is_regexp)
{
dXSARGS;
- PERL_UNUSED_VAR(cv);
if (items != 1)
croak_xs_usage(cv, "sv");
if (!rx)
XSRETURN_UNDEF;
- if (items == 2 && SvTRUE(ST(1))) {
+ if (items == 2 && SvTRUE_NN(ST(1))) {
flags = RXapif_ALL;
} else {
flags = RXapif_ONE;
if (!rx)
XSRETURN_UNDEF;
- if (items == 1 && SvTRUE(ST(0))) {
+ if (items == 1 && SvTRUE_NN(ST(0))) {
flags = RXapif_ALL;
} else {
flags = RXapif_ONE;
} else {
/* Scalar, so use the string that Perl would return */
/* return the pattern in (?msixn:..) format */
-#if PERL_VERSION >= 11
pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
-#else
- pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
- (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
-#endif
PUSHs(pattern);
XSRETURN(1);
}
NOT_REACHED; /* NOTREACHED */
}
+#ifdef HAS_GETCWD
+
+XS(XS_Internals_getcwd)
+{
+ dXSARGS;
+ SV *sv = sv_newmortal();
+
+ if (items != 0)
+ croak_xs_usage(cv, "");
+
+ (void)getcwd_sv(sv);
+
+ SvTAINTED_on(sv);
+ PUSHs(sv);
+ XSRETURN(1);
+}
+
+#endif
+
#include "vutil.h"
#include "vxs.inc"
const char *proto;
};
-static const struct xsub_details details[] = {
+static const struct xsub_details these_details[] = {
{"UNIVERSAL::isa", XS_UNIVERSAL_isa, NULL},
{"UNIVERSAL::can", XS_UNIVERSAL_can, NULL},
{"UNIVERSAL::DOES", XS_UNIVERSAL_DOES, NULL},
{"utf8::unicode_to_native", XS_utf8_unicode_to_native, NULL},
{"Internals::SvREADONLY", XS_Internals_SvREADONLY, "\\[$%@];$"},
{"Internals::SvREFCNT", XS_Internals_SvREFCNT, "\\[$%@];$"},
+ {"Internals::hv_clear_placeholders", XS_Internals_hv_clear_placehold, "\\%"},
{"constant::_make_const", XS_constant__make_const, "\\[$@]"},
{"PerlIO::get_layers", XS_PerlIO_get_layers, "*;@"},
- {"Hash::Util::bucket_ratio", XS_hash_util_bucket_ratio, "\\%"},
- {"Hash::Util::num_buckets", XS_hash_util_num_buckets, "\\%"},
- {"Hash::Util::used_buckets", XS_hash_util_used_buckets, "\\%"},
{"re::is_regexp", XS_re_is_regexp, "$"},
{"re::regname", XS_re_regname, ";$$"},
{"re::regnames", XS_re_regnames, ";$"},
{"re::regnames_count", XS_re_regnames_count, ""},
{"re::regexp_pattern", XS_re_regexp_pattern, "$"},
+#ifdef HAS_GETCWD
+ {"Internals::getcwd", XS_Internals_getcwd, ""},
+#endif
};
STATIC OP*
Perl_boot_core_UNIVERSAL(pTHX)
{
static const char file[] = __FILE__;
- const struct xsub_details *xsub = details;
- const struct xsub_details *end = C_ARRAY_END(details);
+ const struct xsub_details *xsub = these_details;
+ const struct xsub_details *end = C_ARRAY_END(these_details);
do {
newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
CV* to_native_cv = get_cv("utf8::unicode_to_native", 0);
CV* to_unicode_cv = get_cv("utf8::native_to_unicode", 0);
- cv_set_call_checker(to_native_cv,
+ cv_set_call_checker_flags(to_native_cv,
optimize_out_native_convert_function,
- (SV*) to_native_cv);
- cv_set_call_checker(to_unicode_cv,
+ (SV*) to_native_cv, 0);
+ cv_set_call_checker_flags(to_unicode_cv,
optimize_out_native_convert_function,
- (SV*) to_unicode_cv);
+ (SV*) to_unicode_cv, 0);
}
#endif