SvGETMAGIC(sv);
- if (SvROK(sv)) { /* hugdo: */
+ if (SvROK(sv)) {
const char *type;
sv = SvRV(sv);
type = sv_reftype(sv,0);
}
else {
stash = gv_stashsv(sv, 0);
+ if (!stash)
+ stash = gv_stashpv("UNIVERSAL", 0);
}
return stash ? isa_lookup(stash, name, len, flags) : FALSE;
SvGETMAGIC(sv);
- if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
- || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv)))) {
+ if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv)))) {
LEAVE;
return FALSE;
}
*/
void
-Perl_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
+Perl_croak_xs_usage(const CV *const cv, const char *const params)
{
const GV *const gv = CvGV(cv);
const HV *const stash = GvSTASH(gv);
if (HvNAME_get(stash))
- Perl_croak(aTHX_ "Usage: %"HEKf"::%"HEKf"(%s)",
+ Perl_croak_nocontext("Usage: %"HEKf"::%"HEKf"(%s)",
HEKfARG(HvNAME_HEK(stash)),
HEKfARG(GvNAME_HEK(gv)),
params);
else
- Perl_croak(aTHX_ "Usage: %"HEKf"(%s)",
+ Perl_croak_nocontext("Usage: %"HEKf"(%s)",
HEKfARG(GvNAME_HEK(gv)), params);
} else {
/* Pants. I don't think that it should be possible to get here. */
- Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
+ Perl_croak_nocontext("Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
}
}
SvGETMAGIC(sv);
- if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
- || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
+ if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))))
XSRETURN_UNDEF;
ST(0) = boolSV(sv_derived_from_sv(sv, ST(1), 0));
SvGETMAGIC(sv);
- if (!SvOK(sv) || !(SvROK(sv) || (SvPOK(sv) && SvCUR(sv))
- || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv))))
+ if (!SvOK(sv) || !(SvROK(sv) || SvNIOK(sv) || (SvPOK(sv) && SvCUR(sv))
+ ))
XSRETURN_UNDEF;
rv = &PL_sv_undef;
}
else {
pkg = gv_stashsv(sv, 0);
+ if (!pkg)
+ pkg = gv_stashpv("UNIVERSAL", 0);
}
if (pkg) {
GV **gvp;
GV *gv;
SV *sv;
- SV *ret;
const char *undef;
PERL_UNUSED_ARG(cv);
gvp = pkg ? (GV**)hv_fetchs(pkg, "VERSION", FALSE) : NULL;
if (gvp && isGV(gv = *gvp) && (sv = GvSV(gv)) && SvOK(sv)) {
- ret = sv_newmortal();
- sv_setsv(ret, sv);
+ SV * const nsv = sv_newmortal();
+ sv_setsv(nsv, sv);
+ sv = nsv;
+ if ( !sv_isobject(sv) || !sv_derived_from(sv, "version"))
+ upg_version(sv, FALSE);
+
undef = NULL;
}
else {
- sv = ret = &PL_sv_undef;
+ sv = &PL_sv_undef;
undef = "(undef)";
}
}
}
- if ( !sv_derived_from(sv, "version"))
- upg_version(sv, FALSE);
-
- if ( !sv_derived_from(req, "version")) {
+ if ( !sv_isobject(req) || !sv_derived_from(req, "version")) {
/* req may very well be R/O, so create a new object */
req = sv_2mortal( new_version(req) );
}
}
- ST(0) = ret;
+ if ( SvOK(sv) && sv_derived_from(sv, "version") ) {
+ ST(0) = sv_2mortal(vstringify(sv));
+ } else {
+ ST(0) = sv;
+ }
XSRETURN(1);
}
{
SV * lobj = ST(0);
- if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+ if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
lobj = SvRV(lobj);
}
else
{
SV * lobj = ST(0);
- if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+ if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
lobj = SvRV(lobj);
}
else
{
SV * lobj = ST(0);
- if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+ if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
lobj = SvRV(lobj);
}
else
{
SV * lobj = ST(0);
- if (sv_derived_from(lobj, "version") && SvROK(lobj)) {
+ if (sv_isobject(lobj) && sv_derived_from(lobj, "version")) {
lobj = SvRV(lobj);
}
else
SV * robj = ST(1);
const IV swap = (IV)SvIV(ST(2));
- if ( ! sv_derived_from(robj, "version") )
+ if ( !sv_isobject(robj) || !sv_derived_from(robj, "version") )
{
robj = new_version(SvOK(robj) ? robj : newSVpvs_flags("0", SVs_TEMP));
sv_2mortal(robj);
if (items < 1)
croak_xs_usage(cv, "lobj, ...");
SP -= items;
- if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
+ if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version")) {
SV * const lobj = SvRV(ST(0));
- SV * const rs = newSViv( vcmp(lobj,new_version(newSVpvs("0"))) );
+ SV * const rs =
+ newSViv( vcmp(lobj,
+ sv_2mortal(new_version(
+ sv_2mortal(newSVpvs("0"))
+ ))
+ )
+ );
mPUSHs(rs);
PUTBACK;
return;
dXSARGS;
if (items < 1)
croak_xs_usage(cv, "lobj, ...");
- if (sv_derived_from(ST(0), "version") && SvROK(ST(0)))
+ if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version"))
Perl_croak(aTHX_ "operation not supported with version object");
else
Perl_croak(aTHX_ "lobj is not of type version");
if (items != 1)
croak_xs_usage(cv, "lobj");
SP -= items;
- if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
+ if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version")) {
SV * const lobj = ST(0);
if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "alpha", 5 ) )
XSRETURN_YES;
if (items != 1)
croak_xs_usage(cv, "lobj");
SP -= items;
- if (sv_derived_from(ST(0), "version") && SvROK(ST(0))) {
+ if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "version")) {
SV * const lobj = ST(0);
if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "qv", 2 ) )
XSRETURN_YES;
if (items != 1)
croak_xs_usage(cv, "sv");
sv_utf8_encode(ST(0));
+ SvSETMAGIC(ST(0));
XSRETURN_EMPTY;
}
else {
SV * const sv = ST(0);
bool RETVAL;
- if (SvIsCOW(sv)) sv_force_normal(sv);
+ SvPV_force_nolen(sv);
RETVAL = sv_utf8_decode(sv);
+ SvSETMAGIC(sv);
ST(0) = boolSV(RETVAL);
}
XSRETURN(1);
sv = SvRV(svz);
if (items == 1)
- XSRETURN_IV(SvREFCNT(sv) - 1); /* Minus the ref created for us. */
+ XSRETURN_UV(SvREFCNT(sv) - 1); /* Minus the ref created for us. */
else if (items == 2) {
/* I hope you really know what you are doing. */
- SvREFCNT(sv) = SvIV(ST(1));
- XSRETURN_IV(SvREFCNT(sv));
+ SvREFCNT(sv) = SvUV(ST(1)) + 1; /* we free one ref on exit */
+ XSRETURN_UV(SvREFCNT(sv) - 1);
}
XSRETURN_UNDEF; /* Can't happen. */
}
}
sv = POPs;
- gv = MUTABLE_GV(sv);
+ gv = MAYBE_DEREF_GV(sv);
- if (!isGV(sv)) {
- if (SvROK(sv) && isGV(SvRV(sv)))
- gv = MUTABLE_GV(SvRV(sv));
- else if (SvPOKp(sv))
- gv = gv_fetchsv(sv, 0, SVt_PVIO);
- }
+ if (!gv && !SvROK(sv))
+ gv = gv_fetchsv_nomg(sv, 0, SVt_PVIO);
if (gv && (io = GvIO(gv))) {
AV* const av = PerlIO_get_layers(aTHX_ input ?
const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
+ EXTEND(SP, 3); /* Three is the max in all branches: better check just once */
if (details) {
/* Indents of 5? Yuck. */
/* We know that PerlIO_get_layers creates a new SV for
the name and flags, so we can just take a reference
and "steal" it when we free the AV below. */
- XPUSHs(namok
+ PUSHs(namok
? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
: &PL_sv_undef);
- XPUSHs(argok
+ PUSHs(argok
? newSVpvn_flags(SvPVX_const(*argsvp),
SvCUR(*argsvp),
(SvUTF8(*argsvp) ? SVf_UTF8 : 0)
| SVs_TEMP)
: &PL_sv_undef);
- XPUSHs(flgok
+ PUSHs(flgok
? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
: &PL_sv_undef);
nitem += 3;
}
else {
if (namok && argok)
- XPUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
+ PUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
SVfARG(*namsvp),
SVfARG(*argsvp))));
else if (namok)
- XPUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
+ PUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
else
- XPUSHs(&PL_sv_undef);
+ PUSHs(&PL_sv_undef);
nitem++;
if (flgok) {
const IV flags = SvIVX(*flgsvp);
if (flags & PERLIO_F_UTF8) {
- XPUSHs(newSVpvs_flags("utf8", SVs_TEMP));
+ PUSHs(newSVpvs_flags("utf8", SVs_TEMP));
nitem++;
}
}
av = MUTABLE_AV(SvRV(ret));
length = av_len(av);
+ EXTEND(SP, length+1); /* better extend stack just once */
for (i = 0; i <= length; i++) {
entry = av_fetch(av, i, FALSE);
if (!entry)
Perl_croak(aTHX_ "NULL array element in re::regnames()");
- mXPUSHs(SvREFCNT_inc_simple_NN(*entry));
+ mPUSHs(SvREFCNT_inc_simple_NN(*entry));
}
SvREFCNT_dec(ret);
(RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
/* return the pattern and the modifiers */
- XPUSHs(pattern);
- XPUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
+ EXTEND(SP, 2);
+ PUSHs(pattern);
+ PUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
XSRETURN(2);
} else {
/* Scalar, so use the string that Perl would return */
const char *proto;
};
-struct xsub_details details[] = {
+const struct xsub_details details[] = {
{"UNIVERSAL::isa", XS_UNIVERSAL_isa, NULL},
{"UNIVERSAL::can", XS_UNIVERSAL_can, NULL},
{"UNIVERSAL::DOES", XS_UNIVERSAL_DOES, NULL},
{"version::vcmp", XS_version_vcmp, NULL},
{"version::(bool", XS_version_boolean, NULL},
{"version::boolean", XS_version_boolean, NULL},
+ {"version::(+", XS_version_noop, NULL},
+ {"version::(-", XS_version_noop, NULL},
+ {"version::(*", XS_version_noop, NULL},
+ {"version::(/", XS_version_noop, NULL},
+ {"version::(+=", XS_version_noop, NULL},
+ {"version::(-=", XS_version_noop, NULL},
+ {"version::(*=", XS_version_noop, NULL},
+ {"version::(/=", XS_version_noop, NULL},
+ {"version::(abs", XS_version_noop, NULL},
{"version::(nomethod", XS_version_noop, NULL},
{"version::noop", XS_version_noop, NULL},
{"version::is_alpha", XS_version_is_alpha, NULL},
{
dVAR;
static const char file[] = __FILE__;
- struct xsub_details *xsub = details;
+ const struct xsub_details *xsub = details;
const struct xsub_details *end
= details + sizeof(details) / sizeof(details[0]);
newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0);
} while (++xsub < end);
- /* register the overloading (type 'A') magic */
- PL_amagic_generation++;
-
/* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */
{
CV * const cv =
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
* End:
*
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
*/