X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/5513c2cfd695ea6a900a29be8b479bea61614429..91e4b3b3c17af0a2060f42742a68ebbbe15aa657:/universal.c diff --git a/universal.c b/universal.c index e1e1a0b..3217d33 100644 --- a/universal.c +++ b/universal.c @@ -205,7 +205,7 @@ Perl_sv_does_sv(pTHX_ SV *sv, SV *namesv, U32 flags) return FALSE; } - if (sv_isobject(sv)) { + if (SvROK(sv) && SvOBJECT(SvRV(sv))) { classname = sv_ref(NULL,SvRV(sv),TRUE); } else { classname = sv; @@ -294,7 +294,8 @@ A specialised variant of C for emitting the usage message for xsubs works out the package name and subroutine name from C, and then calls C. Hence if C is C<&ouch::awk>, it would call C as: - Perl_croak(aTHX_ "Usage: %"SVf"::%"SVf"(%s)", "ouch" "awk", "eee_yow"); + Perl_croak(aTHX_ "Usage: %"SVf"::%"SVf"(%s)", "ouch" "awk", + "eee_yow"); =cut */ @@ -523,7 +524,7 @@ XS(XS_utf8_native_to_unicode) if (items > 1) croak_xs_usage(cv, "sv"); - ST(0) = sv_2mortal(newSViv(NATIVE_TO_UNI(uv))); + ST(0) = sv_2mortal(newSVuv(NATIVE_TO_UNI(uv))); XSRETURN(1); } @@ -536,7 +537,7 @@ XS(XS_utf8_unicode_to_native) if (items > 1) croak_xs_usage(cv, "sv"); - ST(0) = sv_2mortal(newSViv(UNI_TO_NATIVE(uv))); + ST(0) = sv_2mortal(newSVuv(UNI_TO_NATIVE(uv))); XSRETURN(1); } @@ -562,9 +563,6 @@ XS(XS_Internals_SvREADONLY) /* This is dangerous stuff. */ } else if (items == 2) { if (SvTRUE(ST(1))) { -#ifdef PERL_OLD_COPY_ON_WRITE - if (SvIsCOW(sv)) sv_force_normal(sv); -#endif SvFLAGS(sv) |= SVf_READONLY; XSRETURN_YES; } @@ -591,9 +589,6 @@ XS(XS_constant__make_const) /* This is dangerous stuff. */ sv = SvRV(svz); -#ifdef PERL_OLD_COPY_ON_WRITE - if (SvIsCOW(sv)) sv_force_normal(sv); -#endif SvREADONLY_on(sv); if (SvTYPE(sv) == SVt_PVAV && AvFILLp(sv) != -1) { /* for constant.pm; nobody else should be calling this @@ -903,6 +898,7 @@ XS(XS_re_regexp_pattern) { dXSARGS; REGEXP *re; + I32 const gimme = GIMME_V; EXTEND(SP, 2); SP -= items; @@ -925,7 +921,7 @@ XS(XS_re_regexp_pattern) /* Houston, we have a regex! */ SV *pattern; - if ( GIMME_V == G_ARRAY ) { + if ( gimme == G_ARRAY ) { STRLEN left = 0; char reflags[sizeof(INT_PAT_MODS) + MAX_CHARSET_NAME_LENGTH]; const char *fptr; @@ -965,7 +961,7 @@ XS(XS_re_regexp_pattern) XSRETURN(2); } else { /* Scalar, so use the string that Perl would return */ - /* return the pattern in (?msix:..) format */ + /* return the pattern in (?msixn:..) format */ #if PERL_VERSION >= 11 pattern = sv_2mortal(newSVsv(MUTABLE_SV(re))); #else @@ -977,9 +973,9 @@ XS(XS_re_regexp_pattern) } } else { /* It ain't a regexp folks */ - if ( GIMME_V == G_ARRAY ) { + if ( gimme == G_ARRAY ) { /* return the empty list */ - XSRETURN_UNDEF; + XSRETURN_EMPTY; } else { /* Because of the (?:..) wrapping involved in a stringified pattern it is impossible to get a @@ -995,7 +991,7 @@ XS(XS_re_regexp_pattern) XSRETURN_NO; } } - /* NOT-REACHED */ + NOT_REACHED; /* NOTREACHED */ } #include "vutil.h" @@ -1034,6 +1030,55 @@ static const struct xsub_details details[] = { {"re::regexp_pattern", XS_re_regexp_pattern, "$"}, }; +STATIC OP* +optimize_out_native_convert_function(pTHX_ OP* entersubop, + GV* namegv, + SV* protosv) +{ + /* Optimizes out an identity function, i.e., one that just returns its + * argument. The passed in function is assumed to be an identity function, + * with no checking. This is designed to be called for utf8_to_native() + * and native_to_utf8() on ASCII platforms, as they just return their + * arguments, but it could work on any such function. + * + * The code is mostly just cargo-culted from Memoize::Lift */ + + OP *pushop, *argop; + OP *parent; + SV* prototype = newSVpvs("$"); + + PERL_UNUSED_ARG(protosv); + + assert(entersubop->op_type == OP_ENTERSUB); + + entersubop = ck_entersub_args_proto(entersubop, namegv, prototype); + parent = entersubop; + + SvREFCNT_dec(prototype); + + pushop = cUNOPx(entersubop)->op_first; + if (! OpHAS_SIBLING(pushop)) { + parent = pushop; + pushop = cUNOPx(pushop)->op_first; + } + argop = OpSIBLING(pushop); + + /* Carry on without doing the optimization if it is not something we're + * expecting, so continues to work */ + if ( ! argop + || ! OpHAS_SIBLING(argop) + || OpHAS_SIBLING(OpSIBLING(argop)) + ) { + return entersubop; + } + + /* cut argop from the subtree */ + (void)op_sibling_splice(parent, pushop, 1, NULL); + + op_free(entersubop); + return argop; +} + void Perl_boot_core_UNIVERSAL(pTHX) { @@ -1045,6 +1090,22 @@ Perl_boot_core_UNIVERSAL(pTHX) newXS_flags(xsub->name, xsub->xsub, file, xsub->proto, 0); } while (++xsub < end); +#ifndef EBCDIC + { /* On ASCII platforms these functions just return their argument, so can + be optimized away */ + + 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, + optimize_out_native_convert_function, + (SV*) to_native_cv); + cv_set_call_checker(to_unicode_cv, + optimize_out_native_convert_function, + (SV*) to_unicode_cv); + } +#endif + /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */ { CV * const cv = @@ -1058,11 +1119,5 @@ Perl_boot_core_UNIVERSAL(pTHX) } /* - * Local variables: - * c-indentation-style: bsd - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - * * ex: set ts=8 sts=4 sw=4 et: */