summaryrefslogtreecommitdiff
path: root/dump.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-10-30 09:44:26 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-10-30 12:36:45 -0700
commit8d919b0a35f2b57a6bed2f8355b25b19ac5ad0c5 (patch)
treedeaa4e227975359d48e1f5270ed0a82c53287875 /dump.c
parentf3cb5c3120c59ad2b1843ec808acee239bae8250 (diff)
downloadperl-8d919b0a35f2b57a6bed2f8355b25b19ac5ad0c5.tar.gz
Allow regexp-to-pvlv assignment
Since the xpvlv and regexp structs conflict, we have to find somewhere else to put the regexp struct. I was going to sneak it in SvPVX, allocating a buffer large enough to fit the regexp struct followed by the string, and have SvPVX - sizeof(regexp) point to the struct. But that would make all regexp flag-checking macros fatter, and those are used in hot code. So I came up with another method. Regexp stringification is not speed-critical. So we can move the regexp stringification out of re->sv_u and put it in the regexp struct. Then the regexp struct itself can be pointed to by re->sv_u. So SVt_REGEXPs will have re->sv_any and re->sv_u pointing to the same spot. PVLVs can then have sv->sv_any point to the xpvlv body as usual, but have sv->sv_u point to a regexp struct. All regexp member access can go through sv_u instead of sv_any, which will be no slower than before. Regular expressions will no longer be SvPOK, so we give sv_2pv spec- ial logic for regexps. We don’t need to make the regexp struct larger, as SvLEN is currently always 0 iff mother_re is set. So we can replace the SvLEN field with the pv. SvFAKE is never used without SvPOK or SvSCREAM also set. So we can use that to identify regexps.
Diffstat (limited to 'dump.c')
-rw-r--r--dump.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/dump.c b/dump.c
index 72f7c4e469..4eadad08b2 100644
--- a/dump.c
+++ b/dump.c
@@ -1612,7 +1612,10 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
}
if (type <= SVt_PVLV && !isGV_with_GP(sv)) {
- if (SvPVX_const(sv)) {
+ const bool re = isREGEXP(sv);
+ const char * const ptr =
+ re ? RX_WRAPPED((REGEXP*)sv) : SvPVX_const(sv);
+ if (ptr) {
STRLEN delta;
if (SvOOK(sv)) {
SvOOK_offset(sv, delta);
@@ -1621,18 +1624,22 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
} else {
delta = 0;
}
- Perl_dump_indent(aTHX_ level, file," PV = 0x%"UVxf" ", PTR2UV(SvPVX_const(sv)));
+ Perl_dump_indent(aTHX_ level, file," PV = 0x%"UVxf" ", PTR2UV(ptr));
if (SvOOK(sv)) {
PerlIO_printf(file, "( %s . ) ",
- pv_display(d, SvPVX_const(sv) - delta, delta, 0,
+ pv_display(d, ptr - delta, delta, 0,
pvlim));
}
- PerlIO_printf(file, "%s", pv_display(d, SvPVX_const(sv), SvCUR(sv), SvLEN(sv), pvlim));
+ PerlIO_printf(file, "%s", pv_display(d, ptr, SvCUR(sv),
+ re ? 0 : SvLEN(sv),
+ pvlim));
if (SvUTF8(sv)) /* the 6? \x{....} */
PerlIO_printf(file, " [UTF8 \"%s\"]", sv_uni_display(d, sv, 6 * SvCUR(sv), UNI_DISPLAY_QQ));
PerlIO_printf(file, "\n");
Perl_dump_indent(aTHX_ level, file, " CUR = %"IVdf"\n", (IV)SvCUR(sv));
- Perl_dump_indent(aTHX_ level, file, " LEN = %"IVdf"\n", (IV)SvLEN(sv));
+ if (!re)
+ Perl_dump_indent(aTHX_ level, file, " LEN = %"IVdf"\n",
+ (IV)SvLEN(sv));
}
else
Perl_dump_indent(aTHX_ level, file, " PV = 0\n");
@@ -1958,6 +1965,7 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
do_sv_dump(level+1, file, LvTARG(sv), nest+1, maxnest,
dumpops, pvlim);
}
+ if (isREGEXP(sv)) goto dumpregexp;
if (!isGV_with_GP(sv))
break;
Perl_dump_indent(aTHX_ level, file, " NAME = \"%s\"\n", GvNAME(sv));
@@ -2026,8 +2034,9 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
Perl_dump_indent(aTHX_ level, file, " FLAGS = 0x%"UVxf"\n", (UV)IoFLAGS(sv));
break;
case SVt_REGEXP:
+ dumpregexp:
{
- struct regexp * const r = (struct regexp *)SvANY(sv);
+ struct regexp * const r = ReANY((REGEXP*)sv);
flags = RX_EXTFLAGS((REGEXP*)sv);
sv_setpv(d,"");
append_flags(d, flags, regexp_flags_names);