flag is added to denote whether the PVCV is perl or XSUB.
p4raw-id: //depot/perl@27244
OP * xcv_start;
ANY xcv_xsubany;
} xcv_start_u;
- OP * xcv_root;
- void (*xcv_xsub) (pTHX_ CV*);
+ union {
+ OP * xcv_root;
+ void (*xcv_xsub) (pTHX_ CV*);
+ } xcv_root_u;
GV * xcv_gv;
char * xcv_file;
long xcv_depth; /* >= 2 indicates recursive call */
#define CvSTASH(sv) ((XPVCV*)SvANY(sv))->xcv_stash
#define CvSTART(sv) ((XPVCV*)SvANY(sv))->xcv_start_u.xcv_start
-#define CvROOT(sv) ((XPVCV*)SvANY(sv))->xcv_root
-#define CvXSUB(sv) ((XPVCV*)SvANY(sv))->xcv_xsub
+#define CvROOT(sv) ((XPVCV*)SvANY(sv))->xcv_root_u.xcv_root
+#define CvXSUB(sv) ((XPVCV*)SvANY(sv))->xcv_root_u.xcv_xsub
#define CvXSUBANY(sv) ((XPVCV*)SvANY(sv))->xcv_start_u.xcv_xsubany
#define CvGV(sv) ((XPVCV*)SvANY(sv))->xcv_gv
#define CvFILE(sv) ((XPVCV*)SvANY(sv))->xcv_file
(esp. useful for special XSUBs) */
#define CVf_CONST 0x0400 /* inlinable sub */
#define CVf_OLDSTYLE 0x0800
+#define CVf_ISXSUB 0x1000 /* CV is an XSUB, not pure perl. */
/* This symbol for optimised communication between toke.c and op.c: */
#define CVf_BUILTIN_ATTRS (CVf_METHOD|CVf_LOCKED|CVf_LVALUE|CVf_ASSERTION)
#define CvWEAKOUTSIDE_on(cv) (CvFLAGS(cv) |= CVf_WEAKOUTSIDE)
#define CvWEAKOUTSIDE_off(cv) (CvFLAGS(cv) &= ~CVf_WEAKOUTSIDE)
-#define CvISXSUB(cv) (CvXSUB(cv) ? TRUE : FALSE)
+#define CvISXSUB(cv) (CvFLAGS(cv) & CVf_ISXSUB)
+#define CvISXSUB_on(cv) (CvFLAGS(cv) |= CVf_ISXSUB)
+#define CvISXSUB_off(cv) (CvFLAGS(cv) &= ~CVf_ISXSUB)
+
/*
=head1 CV reference counts and CvOUTSIDE
/* FALL THROUGH */
case SVt_PVFM:
do_hv_dump(level, file, " COMP_STASH", CvSTASH(sv));
- if (!CvISXSUB(sv) && CvSTART(sv))
- Perl_dump_indent(aTHX_ level, file, " START = 0x%"UVxf" ===> %"IVdf"\n", PTR2UV(CvSTART(sv)), (IV)sequence_num(CvSTART(sv)));
- Perl_dump_indent(aTHX_ level, file, " ROOT = 0x%"UVxf"\n", PTR2UV(CvROOT(sv)));
- if (CvROOT(sv) && dumpops)
- do_op_dump(level+1, file, CvROOT(sv));
- Perl_dump_indent(aTHX_ level, file, " XSUB = 0x%"UVxf"\n", PTR2UV(CvXSUB(sv)));
- if (CvISXSUB(sv)) {
+ if (!CvISXSUB(sv)) {
+ if (CvSTART(sv)) {
+ Perl_dump_indent(aTHX_ level, file,
+ " START = 0x%"UVxf" ===> %"IVdf"\n",
+ PTR2UV(CvSTART(sv)),
+ (IV)sequence_num(CvSTART(sv)));
+ }
+ Perl_dump_indent(aTHX_ level, file, " ROOT = 0x%"UVxf"\n",
+ PTR2UV(CvROOT(sv)));
+ if (CvROOT(sv) && dumpops) {
+ do_op_dump(level+1, file, CvROOT(sv));
+ }
+ } else {
SV *constant = cv_const_sv((CV *)sv);
+ Perl_dump_indent(aTHX_ level, file, " XSUB = 0x%"UVxf"\n", PTR2UV(CvXSUB(sv)));
if (constant) {
Perl_dump_indent(aTHX_ level, file, " XSUBANY = 0x%"UVxf
B::OP
CvROOT(cv)
B::CV cv
+ CODE:
+ RETVAL = CvISXSUB(cv) ? NULL : CvROOT(cv);
+ OUTPUT:
+ RETVAL
B::GV
CvGV(cv)
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
# handle DEBUG_LEAKING_SCALARS prefix
$pattern =~ s/^(\s*)(SV =.* at )/(?:$1ALLOCATED at .*?\n)?$1$2/mg;
- $pattern =~ s/^ *\$XSUBANY *\n/
- ($] < 5.009) ? " XSUBANY = 0\n" : '';
+ $pattern =~ s/^ *\$XSUB *\n/
+ ($] < 5.009) ? " XSUB = 0\n XSUBANY = 0\n" : '';
/mge;
+ $pattern =~ s/^ *\$ROOT *\n/
+ ($] < 5.009) ? " ROOT = 0x0\n" : '';
+ /mge;
+
print $pattern, "\n" if $DEBUG;
COMP_STASH = $ADDR\\t"main"
START = $ADDR ===> \\d+
ROOT = $ADDR
- XSUB = 0x0
- $XSUBANY
+ $XSUB
GVGV::GV = $ADDR\\t"main" :: "__ANON__[^"]*"
FILE = ".*\\b(?i:peek\\.t)"
DEPTH = 0
COMP_STASH = $ADDR\\t"main"
START = $ADDR ===> \\d+
ROOT = $ADDR
- XSUB = 0x0
- $XSUBANY
+ $XSUB
GVGV::GV = $ADDR\\t"main" :: "do_test"
FILE = ".*\\b(?i:peek\\.t)"
DEPTH = 1
NV = 0
PROTOTYPE = ""
COMP_STASH = 0x0
- ROOT = 0x0
+ $ROOT
XSUB = $ADDR
XSUBANY = $ADDR \\(CONST SV\\)
SV = PV\\($ADDR\\) at $ADDR
DEPTH = 0
(?: MUTEXP = $ADDR
OWNER = $ADDR
-)? FLAGS = 0x400
+)? FLAGS = 0x1400
OUTSIDE_SEQ = 0
PADLIST = 0x0
OUTSIDE = 0x0 \\(null\\)');
SvREFCNT_dec((SV*)CvXSUBANY(cv).any_ptr);
CvCONST_off(cv);
}
- if (CvXSUB(cv)) {
+ if (CvISXSUB(cv) && CvXSUB(cv)) {
CvXSUB(cv) = 0;
}
/* delete all flags except WEAKOUTSIDE */
CvXSUBANY(cv).any_ptr = const_sv;
CvXSUB(cv) = const_sv_xsub;
CvCONST_on(cv);
+ CvISXSUB_on(cv);
}
else {
GvCV(gv) = NULL;
(void)gv_fetchfile(filename);
CvFILE(cv) = (char *)filename; /* NOTE: not copied, as it is expected to be
an external constant string */
+ CvISXSUB_on(cv);
CvXSUB(cv) = subaddr;
if (name) {
/* NOTE: not refcounted */
CvSTASH(dstr) = hv_dup(CvSTASH(dstr), param);
OP_REFCNT_LOCK;
- CvROOT(dstr) = OpREFCNT_inc(CvROOT(dstr));
+ if (!CvISXSUB(dstr))
+ CvROOT(dstr) = OpREFCNT_inc(CvROOT(dstr));
OP_REFCNT_UNLOCK;
if (CvCONST(dstr)) {
CvXSUBANY(dstr).any_ptr = GvUNIQUE(CvGV(dstr)) ?
OP * xcv_start;
ANY xcv_xsubany;
} xcv_start_u;
- OP * xcv_root;
- void (*xcv_xsub)(pTHX_ CV*);
+ union {
+ OP * xcv_root;
+ void (*xcv_xsub) (pTHX_ CV*);
+ } xcv_root_u;
GV * xcv_gv;
char * xcv_file;
long xcv_depth; /* >= 2 indicates recursive call */
HV* xmg_stash; /* class package */
HV * xcv_stash;
- OP * xcv_start;
- OP * xcv_root;
- void (*xcv_xsub)(pTHX_ CV*);
- ANY xcv_xsubany;
+ union {
+ OP * xcv_start;
+ ANY xcv_xsubany;
+ } xcv_start_u;
+ union {
+ OP * xcv_root;
+ void (*xcv_xsub) (pTHX_ CV*);
+ } xcv_root_u;
GV * xcv_gv;
char * xcv_file;
long xcv_depth; /* >= 2 indicates recursive call */