static const char* const svclassnames[] = {
"B::NULL",
-#if PERL_VERSION < 19
- "B::BIND",
-#endif
"B::IV",
"B::NV",
-#if PERL_VERSION <= 10
- "B::RV",
-#endif
"B::PV",
-#if PERL_VERSION >= 19
"B::INVLIST",
-#endif
"B::PVIV",
"B::PVNV",
"B::PVMG",
-#if PERL_VERSION >= 11
"B::REGEXP",
-#endif
"B::GV",
"B::PVLV",
"B::AV",
#define MY_CXT_KEY "B::_guts" XS_VERSION
typedef struct {
- int x_walkoptree_debug; /* Flag for walkoptree debug hook */
SV * x_specialsv_list[7];
+ int x_walkoptree_debug; /* Flag for walkoptree debug hook */
} my_cxt_t;
START_MY_CXT
#define walkoptree_debug (MY_CXT.x_walkoptree_debug)
#define specialsv_list (MY_CXT.x_specialsv_list)
+
+static void B_init_my_cxt(pTHX_ my_cxt_t * cxt) {
+ cxt->x_specialsv_list[0] = Nullsv;
+ cxt->x_specialsv_list[1] = &PL_sv_undef;
+ cxt->x_specialsv_list[2] = &PL_sv_yes;
+ cxt->x_specialsv_list[3] = &PL_sv_no;
+ cxt->x_specialsv_list[4] = (SV *) pWARN_ALL;
+ cxt->x_specialsv_list[5] = (SV *) pWARN_NONE;
+ cxt->x_specialsv_list[6] = (SV *) pWARN_STD;
+}
+
static opclass
cc_opclass(pTHX_ const OP *o)
{
return ((o->op_private & OPpASSIGN_BACKWARDS) ? OPc_UNOP : OPc_BINOP);
if (o->op_type == OP_AELEMFAST) {
-#if PERL_VERSION <= 14
- if (o->op_flags & OPf_SPECIAL)
- return OPc_BASEOP;
- else
-#endif
#ifdef USE_ITHREADS
return OPc_PADOP;
#else
typedef SV *B__PV;
typedef SV *B__NV;
typedef SV *B__PVMG;
-#if PERL_VERSION >= 11
typedef SV *B__REGEXP;
-#endif
typedef SV *B__PVLV;
typedef SV *B__BM;
typedef SV *B__RV;
/* table that drives most of the B::*OP methods */
-struct OP_methods {
+static const struct OP_methods {
const char *name;
U8 namelen;
U8 type; /* if op_offset_special, access is handled on a case-by-case basis */
{ STR_WITH_LEN("nextop"), OPp, STRUCT_OFFSET(struct loop, op_nextop), },/*10*/
{ STR_WITH_LEN("lastop"), OPp, STRUCT_OFFSET(struct loop, op_lastop), },/*11*/
{ STR_WITH_LEN("pmflags"), U32p, STRUCT_OFFSET(struct pmop, op_pmflags),},/*12*/
-#if PERL_VERSION >= 17
{ STR_WITH_LEN("code_list"),OPp, STRUCT_OFFSET(struct pmop, op_code_list),},/*13*/
-#else
- { STR_WITH_LEN("code_list"),op_offset_special, 0, }, /*13*/
-#endif
{ STR_WITH_LEN("sv"), SVp, STRUCT_OFFSET(struct svop, op_sv), },/*14*/
{ STR_WITH_LEN("gv"), SVp, STRUCT_OFFSET(struct svop, op_sv), },/*15*/
{ STR_WITH_LEN("padix"), PADOFFSETp,STRUCT_OFFSET(struct padop, op_padix),},/*16*/
{ STR_WITH_LEN("filegv"), op_offset_special, 0, },/*21*/
{ STR_WITH_LEN("file"), char_pp, STRUCT_OFFSET(struct cop, cop_file), },/*22*/
{ STR_WITH_LEN("stash"), op_offset_special, 0, },/*23*/
-# if PERL_VERSION < 17
- { STR_WITH_LEN("stashpv"), char_pp, STRUCT_OFFSET(struct cop, cop_stashpv),}, /*24*/
- { STR_WITH_LEN("stashoff"),op_offset_special, 0, },/*25*/
-# else
{ STR_WITH_LEN("stashpv"), op_offset_special, 0, },/*24*/
{ STR_WITH_LEN("stashoff"),PADOFFSETp,STRUCT_OFFSET(struct cop,cop_stashoff),},/*25*/
-# endif
#else
{ STR_WITH_LEN("pmoffset"),op_offset_special, 0, },/*20*/
{ STR_WITH_LEN("filegv"), SVp, STRUCT_OFFSET(struct cop, cop_filegv),},/*21*/
{ STR_WITH_LEN("warnings"),op_offset_special, 0, },/*44*/
{ STR_WITH_LEN("io"), op_offset_special, 0, },/*45*/
{ STR_WITH_LEN("hints_hash"),op_offset_special, 0, },/*46*/
-#if PERL_VERSION >= 17
{ STR_WITH_LEN("slabbed"), op_offset_special, 0, },/*47*/
{ STR_WITH_LEN("savefree"),op_offset_special, 0, },/*48*/
{ STR_WITH_LEN("static"), op_offset_special, 0, },/*49*/
-# if PERL_VERSION >= 19
{ STR_WITH_LEN("folded"), op_offset_special, 0, },/*50*/
- { STR_WITH_LEN("lastsib"), op_offset_special, 0, },/*51*/
+ { STR_WITH_LEN("moresib"), op_offset_special, 0, },/*51*/
{ STR_WITH_LEN("parent"), op_offset_special, 0, },/*52*/
-# endif
-#endif
-#if PERL_VERSION >= 21
{ STR_WITH_LEN("first"), op_offset_special, 0, },/*53*/
{ STR_WITH_LEN("meth_sv"), op_offset_special, 0, },/*54*/
{ STR_WITH_LEN("pmregexp"),op_offset_special, 0, },/*55*/
# else
{ STR_WITH_LEN("rclass"), op_offset_special, 0, },/*56*/
# endif
-#endif
};
#include "const-c.inc"
{
CV *cv;
const char *file = __FILE__;
+ SV *sv;
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] = (SV *) pWARN_ALL;
- specialsv_list[5] = (SV *) pWARN_NONE;
- specialsv_list[6] = (SV *) pWARN_STD;
-
+ B_init_my_cxt(aTHX_ &(MY_CXT));
cv = newXS("B::init_av", intrpvar_sv_common, file);
ASSIGN_COMMON_ALIAS(I, initav);
cv = newXS("B::check_av", intrpvar_sv_common, file);
ASSIGN_COMMON_ALIAS(I, warnhook);
cv = newXS("B::diehook", intrpvar_sv_common, file);
ASSIGN_COMMON_ALIAS(I, diehook);
+ sv = get_sv("B::OP::does_parent", GV_ADDMULTI);
+#ifdef PERL_OP_PARENT
+ sv_setsv(sv, &PL_sv_yes);
+#else
+ sv_setsv(sv, &PL_sv_no);
+#endif
}
#ifndef PL_formfeed
PPCODE:
+#ifdef USE_ITHREADS
+void
+CLONE(...)
+PPCODE:
+ PUTBACK; /* some vars go out of scope now in machine code */
+ {
+ MY_CXT_CLONE;
+ B_init_my_cxt(aTHX_ &(MY_CXT));
+ }
+ return; /* dont execute another implied XSPP PUTBACK */
+#endif
MODULE = B PACKAGE = B::OP
B::OP::savefree = 48
B::OP::static = 49
B::OP::folded = 50
- B::OP::lastsib = 51
+ B::OP::moresib = 51
B::OP::parent = 52
B::METHOP::first = 53
B::METHOP::meth_sv = 54
ret = make_sv_object(aTHX_ (SV *)CopSTASH((COP*)o));
break;
#endif
-#if PERL_VERSION >= 17 || !defined USE_ITHREADS
case 24: /* B::COP::stashpv */
-# if PERL_VERSION >= 17
ret = sv_2mortal(CopSTASH((COP*)o)
&& SvTYPE(CopSTASH((COP*)o)) == SVt_PVHV
? newSVhek(HvNAME_HEK(CopSTASH((COP*)o)))
: &PL_sv_undef);
-# else
- ret = sv_2mortal(newSVpv(CopSTASHPV((COP*)o), 0));
-# endif
break;
-#endif
case 26: /* B::OP::size */
ret = sv_2mortal(newSVuv((UV)(opsizes[cc_opclass(aTHX_ o)])));
break;
case 30: /* B::OP::type */
case 31: /* B::OP::opt */
case 32: /* B::OP::spare */
-#if PERL_VERSION >= 17
case 47: /* B::OP::slabbed */
case 48: /* B::OP::savefree */
case 49: /* B::OP::static */
-#if PERL_VERSION >= 19
case 50: /* B::OP::folded */
- case 51: /* B::OP::lastsib */
-#endif
-#endif
+ case 51: /* B::OP::moresib */
/* These are all bitfields, so we can't take their addresses */
ret = sv_2mortal(newSVuv((UV)(
ix == 30 ? o->op_type
: ix == 48 ? o->op_savefree
: ix == 49 ? o->op_static
: ix == 50 ? o->op_folded
- : ix == 51 ? o->op_lastsib
+ : ix == 51 ? o->op_moresib
: o->op_spare)));
break;
case 33: /* B::LISTOP::children */
PTR2IV(CopHINTHASH_get(cCOPo)));
break;
case 52: /* B::OP::parent */
+#ifdef PERL_OP_PARENT
ret = make_op_object(aTHX_ op_parent(o));
+#else
+ ret = make_op_object(aTHX_ NULL);
+#endif
break;
case 53: /* B::METHOP::first */
/* METHOP struct has an op_first/op_meth_sv union
B::CV cv
PREINIT:
SV *ret;
+ UNOP_AUX_item *aux;
PPCODE:
+ aux = cUNOP_AUXo->op_aux;
switch (o->op_type) {
case OP_MULTIDEREF:
- ret = unop_aux_stringify(o, cv);
+ ret = multideref_stringify(o, cv);
break;
+
+ case OP_ARGELEM:
+ ret = sv_2mortal(Perl_newSVpvf(aTHX_ "%"UVuf,
+ PTR2UV(aux)));
+ break;
+
+ case OP_ARGCHECK:
+ ret = Perl_newSVpvf(aTHX_ "%"UVuf",%"UVuf, aux[0].uv, aux[1].uv);
+ if (aux[2].iv)
+ Perl_sv_catpvf(aTHX_ ret, ",%c", (char)aux[2].iv);
+ ret = sv_2mortal(ret);
+ break;
+
default:
ret = sv_2mortal(newSVpvn("", 0));
}
+
ST(0) = ret;
XSRETURN(1);
aux_list(o, cv)
B::OP o
B::CV cv
+ PREINIT:
+ UNOP_AUX_item *aux;
PPCODE:
PERL_UNUSED_VAR(cv); /* not needed on unthreaded builds */
+ aux = cUNOP_AUXo->op_aux;
switch (o->op_type) {
default:
XSRETURN(0); /* by default, an empty list */
+ case OP_ARGELEM:
+ XPUSHs(sv_2mortal(newSVuv(PTR2UV(aux))));
+ XSRETURN(1);
+ break;
+
+ case OP_ARGCHECK:
+ EXTEND(SP, 3);
+ PUSHs(sv_2mortal(newSVuv(aux[0].uv)));
+ PUSHs(sv_2mortal(newSVuv(aux[1].uv)));
+ PUSHs(sv_2mortal(aux[2].iv ? Perl_newSVpvf(aTHX_ "%c",
+ (char)aux[2].iv) : &PL_sv_no));
+ break;
+
case OP_MULTIDEREF:
#ifdef USE_ITHREADS
# define ITEM_SV(item) *av_fetch(comppad, (item)->pad_offset, FALSE);
PAD *comppad = PadlistARRAY(padlist)[1];
#endif
- EXTEND(SP, len);
+ /* len should never be big enough to truncate or wrap */
+ assert(len <= SSize_t_MAX);
+ EXTEND(SP, (SSize_t)len);
PUSHs(sv_2mortal(newSViv(actions)));
while (!last) {
actions = (++items)->uv;
PUSHs(sv_2mortal(newSVuv(actions)));
continue;
+ NOT_REACHED; /* NOTREACHED */
case MDEREF_HV_padhv_helem:
is_hash = TRUE;
+ /* FALLTHROUGH */
case MDEREF_AV_padav_aelem:
PUSHs(sv_2mortal(newSVuv((++items)->pad_offset)));
goto do_elem;
+ NOT_REACHED; /* NOTREACHED */
case MDEREF_HV_gvhv_helem:
is_hash = TRUE;
+ /* FALLTHROUGH */
case MDEREF_AV_gvav_aelem:
sv = ITEM_SV(++items);
PUSHs(make_sv_object(aTHX_ sv));
goto do_elem;
+ NOT_REACHED; /* NOTREACHED */
case MDEREF_HV_gvsv_vivify_rv2hv_helem:
is_hash = TRUE;
+ /* FALLTHROUGH */
case MDEREF_AV_gvsv_vivify_rv2av_aelem:
sv = ITEM_SV(++items);
PUSHs(make_sv_object(aTHX_ sv));
goto do_vivify_rv2xv_elem;
+ NOT_REACHED; /* NOTREACHED */
case MDEREF_HV_padsv_vivify_rv2hv_helem:
is_hash = TRUE;
+ /* FALLTHROUGH */
case MDEREF_AV_padsv_vivify_rv2av_aelem:
PUSHs(sv_2mortal(newSVuv((++items)->pad_offset)));
goto do_vivify_rv2xv_elem;
+ NOT_REACHED; /* NOTREACHED */
case MDEREF_HV_pop_rv2hv_helem:
case MDEREF_HV_vivify_rv2hv_helem:
is_hash = TRUE;
+ /* FALLTHROUGH */
do_vivify_rv2xv_elem:
case MDEREF_AV_pop_rv2av_aelem:
case MDEREF_AV_vivify_rv2av_aelem:
#define PVMG_stash_ix sv_SVp | STRUCT_OFFSET(struct xpvmg, xmg_stash)
-#if PERL_VERSION > 18
-# define PVBM_useful_ix sv_IVp | STRUCT_OFFSET(struct xpviv, xiv_u.xivu_iv)
-#elif PERL_VERSION > 14
-# define PVBM_useful_ix sv_I32p | STRUCT_OFFSET(struct xpvgv, xnv_u.xbm_s.xbm_useful)
-#else
-#define PVBM_useful_ix sv_I32p | STRUCT_OFFSET(struct xpvgv, xiv_u.xivu_i32)
-#endif
+#define PVBM_useful_ix sv_IVp | STRUCT_OFFSET(struct xpviv, xiv_u.xivu_iv)
#define PVLV_targoff_ix sv_U32p | STRUCT_OFFSET(struct xpvlv, xlv_targoff)
#define PVLV_targlen_ix sv_U32p | STRUCT_OFFSET(struct xpvlv, xlv_targlen)
#define PVAV_max_ix sv_SSize_tp | STRUCT_OFFSET(struct xpvav, xav_max)
#define PVCV_stash_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_stash)
-#if PERL_VERSION > 17 || (PERL_VERSION == 17 && PERL_SUBVERSION >= 3)
-# define PVCV_gv_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_gv_u.xcv_gv)
-#else
-# define PVCV_gv_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_gv)
-#endif
+#define PVCV_gv_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_gv_u.xcv_gv)
#define PVCV_file_ix sv_char_pp | STRUCT_OFFSET(struct xpvcv, xcv_file)
#define PVCV_outside_ix sv_SVp | STRUCT_OFFSET(struct xpvcv, xcv_outside)
#define PVCV_outside_seq_ix sv_U32p | STRUCT_OFFSET(struct xpvcv, xcv_outside_seq)
#define PVCV_flags_ix sv_U32p | STRUCT_OFFSET(struct xpvcv, xcv_flags)
#define PVHV_max_ix sv_STRLENp | STRUCT_OFFSET(struct xpvhv, xhv_max)
-
-#if PERL_VERSION > 12
#define PVHV_keys_ix sv_STRLENp | STRUCT_OFFSET(struct xpvhv, xhv_keys)
-#else
-#define PVHV_keys_ix sv_IVp | STRUCT_OFFSET(struct xpvhv, xhv_keys)
-#endif
# The type checking code in B has always been identical for all SV types,
# irrespective of whether the action is actually defined on that SV.
SvNV(sv)
B::NV sv
-#if PERL_VERSION < 11
-
-MODULE = B PACKAGE = B::RV PREFIX = Sv
-
-void
-SvRV(sv)
- B::RV sv
- PPCODE:
- PUSHs(make_sv_object(aTHX_ SvRV(sv)));
-
-#else
-
MODULE = B PACKAGE = B::REGEXP
void
PUSHs(newSVpvn_flags(RX_PRECOMP(sv), RX_PRELEN(sv), SVs_TEMP));
} else if (ix == 2) {
PUSHs(make_sv_object(aTHX_ (SV *)ReANY(sv)->qr_anoncv));
- } else if (ix) {
- dXSTARG;
- PUSHu(RX_COMPFLAGS(sv));
} else {
dXSTARG;
+ if (ix)
+ PUSHu(RX_COMPFLAGS(sv));
+ else
/* FIXME - can we code this method more efficiently? */
- PUSHi(PTR2IV(sv));
+ PUSHi(PTR2IV(sv));
}
-#endif
-
MODULE = B PACKAGE = B::PV
void
BmPREVIOUS(sv)
B::BM sv
CODE:
-#if PERL_VERSION >= 19
PERL_UNUSED_VAR(sv);
-#endif
RETVAL = BmPREVIOUS(sv);
OUTPUT:
RETVAL
BmRARE(sv)
B::BM sv
CODE:
-#if PERL_VERSION >= 19
PERL_UNUSED_VAR(sv);
-#endif
RETVAL = BmRARE(sv);
OUTPUT:
RETVAL
CODE:
ST(0) = make_sv_object(aTHX_ (SV*)CvGV(cv));
-#if PERL_VERSION > 17
-
SV *
NAME_HEK(cv)
B::CV cv
OUTPUT:
RETVAL
-#endif
-
MODULE = B PACKAGE = B::HV PREFIX = Hv
STRLEN
PPCODE:
if (HvUSEDKEYS(hv) > 0) {
HE *he;
+ SSize_t extend_size;
(void)hv_iterinit(hv);
- EXTEND(sp, HvUSEDKEYS(hv) * 2);
+ /* 2*HvUSEDKEYS() should never be big enough to truncate or wrap */
+ assert(HvUSEDKEYS(hv) <= (SSize_t_MAX >> 1));
+ extend_size = (SSize_t)HvUSEDKEYS(hv) * 2;
+ EXTEND(sp, extend_size);
while ((he = hv_iternext(hv))) {
if (HeSVKEY(he)) {
mPUSHs(HeSVKEY(he));
/* backward-compatibility hack, which should be removed if the
flags field becomes large enough to hold SVf_FAKE (and
PADNAMEt_OUTER should be renumbered to match SVf_FAKE) */
- STATIC_ASSERT_STMT(SVf_FAKE >= 1<<(sizeof(PadnameFLAGS(pn)) * 8));
+ STATIC_ASSERT_STMT(SVf_FAKE >= 1<<(sizeof(PadnameFLAGS((B__PADNAME)NULL)) * 8));
if (PadnameOUTER(pn))
RETVAL |= SVf_FAKE;
OUTPUT: