X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/b55685ae0907b7da1c668988d736c684531f41ac..089d5d592af05e188741d15eb055de559f1bf619:/ext/B/B.xs diff --git a/ext/B/B.xs b/ext/B/B.xs index f9c8647..4370c3e 100644 --- a/ext/B/B.xs +++ b/ext/B/B.xs @@ -21,6 +21,9 @@ typedef FILE * InputStream; static const char* const svclassnames[] = { "B::NULL", +#if PERL_VERSION >= 9 + "B::BIND", +#endif "B::IV", "B::NV", "B::RV", @@ -28,7 +31,9 @@ static const char* const svclassnames[] = { "B::PVIV", "B::PVNV", "B::PVMG", +#if PERL_VERSION <= 8 "B::BM", +#endif #if PERL_VERSION >= 9 "B::GV", #endif @@ -112,9 +117,20 @@ cc_opclass(pTHX_ const OP *o) if (o->op_type == OP_SASSIGN) return ((o->op_private & OPpASSIGN_BACKWARDS) ? OPc_UNOP : OPc_BINOP); + if (o->op_type == OP_AELEMFAST) { + if (o->op_flags & OPf_SPECIAL) + return OPc_BASEOP; + else +#ifdef USE_ITHREADS + return OPc_PADOP; +#else + return OPc_SVOP; +#endif + } + #ifdef USE_ITHREADS if (o->op_type == OP_GV || o->op_type == OP_GVSV || - o->op_type == OP_AELEMFAST || o->op_type == OP_RCATLINE) + o->op_type == OP_RCATLINE) return OPc_PADOP; #endif @@ -235,6 +251,71 @@ make_sv_object(pTHX_ SV *arg, SV *sv) return arg; } +#if PERL_VERSION >= 9 +static SV * +make_temp_object(pTHX_ SV *arg, SV *temp) +{ + SV *target; + const char *const type = svclassnames[SvTYPE(temp)]; + const IV iv = PTR2IV(temp); + + target = newSVrv(arg, type); + sv_setiv(target, iv); + + /* Need to keep our "temp" around as long as the target exists. + Simplest way seems to be to hang it from magic, and let that clear + it up. No vtable, so won't actually get in the way of anything. */ + sv_magicext(target, temp, PERL_MAGIC_sv, NULL, NULL, 0); + /* magic object has had its reference count increased, so we must drop + our reference. */ + SvREFCNT_dec(temp); + return arg; +} + +static SV * +make_warnings_object(pTHX_ SV *arg, STRLEN *warnings) +{ + const char *type = 0; + dMY_CXT; + IV iv = sizeof(specialsv_list)/sizeof(SV*); + + /* Counting down is deliberate. Before the split between make_sv_object + and make_warnings_obj there appeared to be a bug - Nullsv and pWARN_STD + were both 0, so you could never get a B::SPECIAL for pWARN_STD */ + + while (iv--) { + if ((SV*)warnings == specialsv_list[iv]) { + type = "B::SPECIAL"; + break; + } + } + if (type) { + sv_setiv(newSVrv(arg, type), iv); + return arg; + } else { + /* B assumes that warnings are a regular SV. Seems easier to keep it + happy by making them into a regular SV. */ + return make_temp_object(aTHX_ arg, + newSVpvn((char *)(warnings + 1), *warnings)); + } +} + +static SV * +make_cop_io_object(pTHX_ SV *arg, COP *cop) +{ + SV *const value = newSV(0); + + Perl_emulate_cop_io(aTHX_ cop, value); + + if(SvOK(value)) { + return make_temp_object(aTHX_ arg, newSVsv(value)); + } else { + SvREFCNT_dec(value); + return make_sv_object(aTHX_ arg, NULL); + } +} +#endif + static SV * make_mg_object(pTHX_ SV *arg, MAGIC *mg) { @@ -406,7 +487,12 @@ walkoptree(pTHX_ SV *opsv, const char *method) } } if (o && (cc_opclass(aTHX_ o) == OPc_PMOP) && o->op_type != OP_PUSHRE - && (kid = cPMOPo->op_pmreplroot)) +#if PERL_VERSION >= 9 + && (kid = cPMOPo->op_pmreplrootu.op_pmreplroot) +#else + && (kid = cPMOPo->op_pmreplroot) +#endif + ) { sv_setiv(newSVrv(opsv, cc_opclassname(aTHX_ kid)), PTR2IV(kid)); walkoptree(aTHX_ opsv, method); @@ -432,7 +518,11 @@ oplist(pTHX_ OP *o, SV **SP) XPUSHs(opsv); switch (o->op_type) { case OP_SUBST: +#if PERL_VERSION >= 9 + SP = oplist(aTHX_ cPMOPo->op_pmstashstartu.op_pmreplstart, SP); +#else SP = oplist(aTHX_ cPMOPo->op_pmreplstart, SP); +#endif continue; case OP_SORT: if (o->op_flags & OPf_STACKED && o->op_flags & OPf_SPECIAL) { @@ -485,6 +575,10 @@ typedef GV *B__GV; typedef IO *B__IO; typedef MAGIC *B__MAGIC; +typedef HE *B__HE; +#if PERL_VERSION >= 9 +typedef struct refcounted_he *B__RHE; +#endif MODULE = B PACKAGE = B PREFIX = B_ @@ -492,18 +586,18 @@ PROTOTYPES: DISABLE BOOT: { - HV *stash = gv_stashpvn("B", 1, TRUE); + HV *stash = gv_stashpvn("B", 1, GV_ADD); AV *export_ok = perl_get_av("B::EXPORT_OK",TRUE); MY_CXT_INIT; specialsv_list[0] = Nullsv; specialsv_list[1] = &PL_sv_undef; specialsv_list[2] = &PL_sv_yes; specialsv_list[3] = &PL_sv_no; - specialsv_list[4] = pWARN_ALL; - specialsv_list[5] = pWARN_NONE; - specialsv_list[6] = pWARN_STD; + specialsv_list[4] = (SV *) pWARN_ALL; + specialsv_list[5] = (SV *) pWARN_NONE; + specialsv_list[6] = (SV *) pWARN_STD; #if PERL_VERSION <= 8 -# define CVf_ASSERTION 0 +# define OPpPAD_STATE 0 #endif #include "defsubs.h" } @@ -512,11 +606,17 @@ BOOT: #define B_init_av() PL_initav #define B_inc_gv() PL_incgv #define B_check_av() PL_checkav_save +#if PERL_VERSION > 8 +# define B_unitcheck_av() PL_unitcheckav_save +#else +# define B_unitcheck_av() NULL +#endif #define B_begin_av() PL_beginav_save #define B_end_av() PL_endav #define B_main_root() PL_main_root #define B_main_start() PL_main_start #define B_amagic_generation() PL_amagic_generation +#define B_sub_generation() PL_sub_generation #define B_defstash() PL_defstash #define B_curstash() PL_curstash #define B_dowarn() PL_dowarn @@ -535,6 +635,13 @@ B_init_av() B::AV B_check_av() +#if PERL_VERSION >= 9 + +B::AV +B_unitcheck_av() + +#endif + B::AV B_begin_av() @@ -563,6 +670,9 @@ B_main_start() long B_amagic_generation() +long +B_sub_generation() + B::AV B_comppadlist() @@ -735,7 +845,6 @@ threadsv_names() #define OP_type(o) o->op_type #if PERL_VERSION >= 9 # define OP_opt(o) o->op_opt -# define OP_static(o) o->op_static #else # define OP_seq(o) o->op_seq #endif @@ -802,10 +911,6 @@ U8 OP_opt(o) B::OP o -U8 -OP_static(o) - B::OP o - #else U16 @@ -875,22 +980,27 @@ LISTOP_children(o) OUTPUT: RETVAL -#define PMOP_pmreplroot(o) o->op_pmreplroot -#define PMOP_pmreplstart(o) o->op_pmreplstart +#if PERL_VERSION >= 9 +# define PMOP_pmreplstart(o) o->op_pmstashstartu.op_pmreplstart +#else +# define PMOP_pmreplstart(o) o->op_pmreplstart +# define PMOP_pmpermflags(o) o->op_pmpermflags +# define PMOP_pmdynflags(o) o->op_pmdynflags +#endif #define PMOP_pmnext(o) o->op_pmnext #define PMOP_pmregexp(o) PM_GETRE(o) #ifdef USE_ITHREADS #define PMOP_pmoffset(o) o->op_pmoffset -#define PMOP_pmstashpv(o) o->op_pmstashpv +#define PMOP_pmstashpv(o) PmopSTASHPV(o); #else -#define PMOP_pmstash(o) o->op_pmstash +#define PMOP_pmstash(o) PmopSTASH(o); #endif #define PMOP_pmflags(o) o->op_pmflags -#define PMOP_pmpermflags(o) o->op_pmpermflags -#define PMOP_pmdynflags(o) o->op_pmdynflags MODULE = B PACKAGE = B::PMOP PREFIX = PMOP_ +#if PERL_VERSION <= 8 + void PMOP_pmreplroot(o) B::PMOP o @@ -900,26 +1010,55 @@ PMOP_pmreplroot(o) root = o->op_pmreplroot; /* OP_PUSHRE stores an SV* instead of an OP* in op_pmreplroot */ if (o->op_type == OP_PUSHRE) { -#ifdef USE_ITHREADS +# ifdef USE_ITHREADS sv_setiv(ST(0), INT2PTR(PADOFFSET,root) ); -#else +# else sv_setiv(newSVrv(ST(0), root ? svclassnames[SvTYPE((SV*)root)] : "B::SV"), PTR2IV(root)); -#endif +# endif } else { sv_setiv(newSVrv(ST(0), cc_opclassname(aTHX_ root)), PTR2IV(root)); } +#else + +void +PMOP_pmreplroot(o) + B::PMOP o + CODE: + ST(0) = sv_newmortal(); + if (o->op_type == OP_PUSHRE) { +# ifdef USE_ITHREADS + sv_setiv(ST(0), o->op_pmreplrootu.op_pmtargetoff); +# else + GV *const target = o->op_pmreplrootu.op_pmtargetgv; + sv_setiv(newSVrv(ST(0), target ? + svclassnames[SvTYPE((SV*)target)] : "B::SV"), + PTR2IV(target)); +# endif + } + else { + OP *const root = o->op_pmreplrootu.op_pmreplroot; + sv_setiv(newSVrv(ST(0), cc_opclassname(aTHX_ root)), + PTR2IV(root)); + } + +#endif + B::OP PMOP_pmreplstart(o) B::PMOP o +#if PERL_VERSION < 9 + B::PMOP PMOP_pmnext(o) B::PMOP o +#endif + #ifdef USE_ITHREADS IV @@ -942,6 +1081,8 @@ U32 PMOP_pmflags(o) B::PMOP o +#if PERL_VERSION < 9 + U32 PMOP_pmpermflags(o) B::PMOP o @@ -950,6 +1091,8 @@ U8 PMOP_pmdynflags(o) B::PMOP o +#endif + void PMOP_precomp(o) B::PMOP o @@ -960,6 +1103,20 @@ PMOP_precomp(o) if (rx) sv_setpvn(ST(0), rx->precomp, rx->prelen); +#if PERL_VERSION >= 9 + +void +PMOP_reflags(o) + B::PMOP o + REGEXP * rx = NO_INIT + CODE: + ST(0) = sv_newmortal(); + rx = PM_GETRE(o); + if (rx) + sv_setuv(ST(0), rx->extflags); + +#endif + #define SVOP_sv(o) cSVOPo->op_sv #define SVOP_gv(o) ((GV*)cSVOPo->op_sv) @@ -1042,10 +1199,13 @@ LOOP_lastop(o) #define COP_file(o) CopFILE(o) #define COP_filegv(o) CopFILEGV(o) #define COP_cop_seq(o) o->cop_seq -#define COP_arybase(o) o->cop_arybase +#define COP_arybase(o) CopARYBASE_get(o) #define COP_line(o) CopLINE(o) -#define COP_warnings(o) o->cop_warnings -#define COP_io(o) o->cop_io +#define COP_hints(o) CopHINTS_get(o) +#if PERL_VERSION < 9 +# define COP_warnings(o) o->cop_warnings +# define COP_io(o) o->cop_io +#endif MODULE = B PACKAGE = B::COP PREFIX = COP_ @@ -1082,6 +1242,32 @@ U32 COP_line(o) B::COP o +#if PERL_VERSION >= 9 + +void +COP_warnings(o) + B::COP o + PPCODE: + ST(0) = make_warnings_object(aTHX_ sv_newmortal(), o->cop_warnings); + XSRETURN(1); + +void +COP_io(o) + B::COP o + PPCODE: + ST(0) = make_cop_io_object(aTHX_ sv_newmortal(), o); + XSRETURN(1); + +B::RHE +COP_hints_hash(o) + B::COP o + CODE: + RETVAL = o->cop_hints_hash; + OUTPUT: + RETVAL + +#else + B::SV COP_warnings(o) B::COP o @@ -1090,6 +1276,12 @@ B::SV COP_io(o) B::COP o +#endif + +U32 +COP_hints(o) + B::COP o + MODULE = B PACKAGE = B::SV U32 @@ -1184,6 +1376,22 @@ NV SvNVX(sv) B::NV sv +U32 +COP_SEQ_RANGE_LOW(sv) + B::NV sv + +U32 +COP_SEQ_RANGE_HIGH(sv) + B::NV sv + +U32 +PARENT_PAD_INDEX(sv) + B::NV sv + +U32 +PARENT_FAKELEX_FLAGS(sv) + B::NV sv + MODULE = B PACKAGE = B::RV PREFIX = Sv B::SV @@ -1232,13 +1440,16 @@ SvPV(sv) sv_setpvn(ST(0), NULL, 0); } +# This used to read 257. I think that that was buggy - should have been 258. +# (The "\0", the flags byte, and 256 for the table. Not that anything +# anywhere calls this method. NWC. void SvPVBM(sv) B::PV sv CODE: ST(0) = sv_newmortal(); sv_setpvn(ST(0), SvPVX_const(sv), - SvCUR(sv) + (SvTYPE(sv) == SVt_PVBM ? 257 : 0)); + SvCUR(sv) + (SvVALID(sv) ? 256 + PERL_FBM_TABLE_OFFSET : 0)); STRLEN @@ -1308,7 +1519,7 @@ IV MgREGEX(mg) B::MAGIC mg CODE: - if( mg->mg_type == 'r' ) { + if(mg->mg_type == PERL_MAGIC_qr) { RETVAL = MgREGEX(mg); } else { @@ -1321,8 +1532,9 @@ SV* precomp(mg) B::MAGIC mg CODE: - if (mg->mg_type == 'r') { + if (mg->mg_type == PERL_MAGIC_qr) { REGEXP* rx = (REGEXP*)mg->mg_obj; + RETVAL = Nullsv; if( rx ) RETVAL = newSVpvn( rx->precomp, rx->prelen ); } @@ -1374,7 +1586,7 @@ I32 BmUSEFUL(sv) B::BM sv -U16 +U32 BmPREVIOUS(sv) B::BM sv @@ -1390,7 +1602,7 @@ BmTABLE(sv) CODE: str = SvPV(sv, len); /* Boyer-Moore table is just after string and its safety-margin \0 */ - ST(0) = sv_2mortal(newSVpvn(str + len + 1, 256)); + ST(0) = sv_2mortal(newSVpvn(str + len + PERL_FBM_TABLE_OFFSET, 256)); MODULE = B PACKAGE = B::GV PREFIX = Gv @@ -1563,6 +1775,17 @@ SSize_t AvMAX(av) B::AV av +#if PERL_VERSION < 9 + + +#define AvOFF(av) ((XPVAV*)SvANY(av))->xof_off + +IV +AvOFF(av) + B::AV av + +#endif + void AvARRAY(av) B::AV av @@ -1584,6 +1807,16 @@ AvARRAYelt(av, idx) else XPUSHs(make_sv_object(aTHX_ sv_newmortal(), NULL)); +#if PERL_VERSION < 9 + +MODULE = B PACKAGE = B::AV + +U8 +AvFLAGS(av) + B::AV av + +#endif + MODULE = B PACKAGE = B::FM PREFIX = Fm IV @@ -1603,10 +1836,18 @@ CvSTASH(cv) B::OP CvSTART(cv) B::CV cv + CODE: + RETVAL = CvISXSUB(cv) ? NULL : CvSTART(cv); + OUTPUT: + RETVAL B::OP CvROOT(cv) B::CV cv + CODE: + RETVAL = CvISXSUB(cv) ? NULL : CvROOT(cv); + OUTPUT: + RETVAL B::GV CvGV(cv) @@ -1636,7 +1877,7 @@ void CvXSUB(cv) B::CV cv CODE: - ST(0) = sv_2mortal(newSViv(PTR2IV(CvXSUB(cv)))); + ST(0) = sv_2mortal(newSViv(CvISXSUB(cv) ? PTR2IV(CvXSUB(cv)) : 0)); void @@ -1645,7 +1886,7 @@ CvXSUBANY(cv) CODE: ST(0) = CvCONST(cv) ? make_sv_object(aTHX_ sv_newmortal(),(SV *)CvXSUBANY(cv).any_ptr) : - sv_2mortal(newSViv(CvXSUBANY(cv).any_iv)); + sv_2mortal(newSViv(CvISXSUB(cv) ? CvXSUBANY(cv).any_iv : 0)); MODULE = B PACKAGE = B::CV @@ -1682,6 +1923,14 @@ char * HvNAME(hv) B::HV hv +#if PERL_VERSION < 9 + +B::PMOP +HvPMROOT(hv) + B::HV hv + +#endif + void HvARRAY(hv) B::HV hv @@ -1697,3 +1946,31 @@ HvARRAY(hv) PUSHs(make_sv_object(aTHX_ sv_newmortal(), sv)); } } + +MODULE = B PACKAGE = B::HE PREFIX = He + +B::SV +HeVAL(he) + B::HE he + +U32 +HeHASH(he) + B::HE he + +B::SV +HeSVKEY_force(he) + B::HE he + +MODULE = B PACKAGE = B::RHE PREFIX = RHE_ + +#if PERL_VERSION >= 9 + +SV* +RHE_HASH(h) + B::RHE h + CODE: + RETVAL = newRV( (SV*)Perl_refcounted_he_chain_2hv(aTHX_ h) ); + OUTPUT: + RETVAL + +#endif