"PVIV",
"PVNV",
"PVMG",
- "ORANGE",
+ "REGEXP",
"PVGV",
"PVLV",
"PVAV",
"PVIV",
"PVNV",
"PVMG",
- "ORANGE",
+ "REGEXP",
"GV",
"PVLV",
"AV",
@B::PVIV::ISA = qw(B::PV B::IV);
@B::PVNV::ISA = qw(B::PVIV B::NV);
@B::PVMG::ISA = 'B::PVNV';
-@B::ORANGE::ISA = 'B::PVMG' if $] >= 5.011;
+@B::REGEXP::ISA = 'B::PVMG' if $] >= 5.011;
# Change in the inheritance hierarchy post 5.9.0
@B::PVLV::ISA = $] > 5.009 ? 'B::GV' : 'B::PVMG';
# BM is eliminated post 5.9.5, but effectively is a specialisation of GV now.
"B::BM",
#endif
#if PERL_VERSION >= 11
- "B::ORANGE",
+ "B::REGEXP",
#endif
#if PERL_VERSION >= 9
"B::GV",
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;
SvSTASH(sv)
B::PVMG sv
+MODULE = B PACKAGE = B::REGEXP
+
+#if PERL_VERSION >= 11
+
+IV
+REGEX(sv)
+ B::PVMG sv
+ CODE:
+ RETVAL = PTR2IV(((struct xregexp *)SvANY(sv))->xrx_regexp);
+ OUTPUT:
+ RETVAL
+
+SV*
+precomp(sv)
+ B::PVMG sv
+ REGEXP* rx = NO_INIT
+ CODE:
+ rx = ((struct xregexp *)SvANY(sv))->xrx_regexp;
+ /* FIXME - UTF-8? And the equivalent precomp methods? */
+ RETVAL = newSVpvn( rx->precomp, rx->prelen );
+ OUTPUT:
+ RETVAL
+
+#endif
+
#define MgMOREMAGIC(mg) mg->mg_moremagic
#define MgPRIVATE(mg) mg->mg_private
#define MgTYPE(mg) mg->mg_type
'$. has no more magic' );
}
-ok(B::svref_2object(qr/foo/)->MAGIC->precomp() eq 'foo', 'Get string from qr//');
-like(B::svref_2object(qr/foo/)->MAGIC->REGEX(), qr/\d+/, "REGEX() returns numeric value");
+my $r = qr/foo/;
+my $obj = B::svref_2object($r);
+my $regexp = ($] < 5.011) ? $obj->MAGIC : $obj;
+ok($regexp->precomp() eq 'foo', 'Get string from qr//');
+like($regexp->REGEX(), qr/\d+/, "REGEX() returns numeric value");
my $iv = 1;
my $iv_ref = B::svref_2object(\$iv);
is(ref $iv_ref, "B::IV", "Test B:IV return from svref_2object");
B::IV T_SV_OBJ
B::NV T_SV_OBJ
B::PVMG T_SV_OBJ
+B::REGEXP T_SV_OBJ
B::PVLV T_SV_OBJ
B::BM T_SV_OBJ
B::RV T_SV_OBJ
REFCNT = 1
FLAGS = \\(ROK\\)
RV = $ADDR
- SV = ORANGE\\($ADDR\\) at $ADDR
+ SV = REGEXP\\($ADDR\\) at $ADDR
REFCNT = 1
- FLAGS = \\(OBJECT,SMG\\)
+ FLAGS = \\(\\)
IV = 0
NV = 0
- PV = 0
- MAGIC = $ADDR
- MG_VIRTUAL = $ADDR
- MG_TYPE = PERL_MAGIC_qr\(r\)
- MG_OBJ = $ADDR
- PAT = "\(\?-xism:tic\)"
- REFCNT = 2
- STASH = $ADDR\\t"Regexp"');
+ PV = 0');
} else {
do_test(15,
qr(tic),
like(overload::StrVal(sub{1}), qr/^CODE\(0x[0-9a-f]+\)$/);
like(overload::StrVal(\*GLOB), qr/^GLOB\(0x[0-9a-f]+\)$/);
like(overload::StrVal(\$o), qr/^REF\(0x[0-9a-f]+\)$/);
- like(overload::StrVal(qr/a/), qr/^Regexp=ORANGE\(0x[0-9a-f]+\)$/);
+ like(overload::StrVal(qr/a/), qr/^Regexp\(0x[0-9a-f]+\)$/);
like(overload::StrVal($o), qr/^perl31793=ARRAY\(0x[0-9a-f]+\)$/);
like(overload::StrVal($of), qr/^perl31793_fb=ARRAY\(0x[0-9a-f]+\)$/);
like(overload::StrVal($no), qr/^no_overload=ARRAY\(0x[0-9a-f]+\)$/);
dSP;
register PMOP *pm = (PMOP*)cLOGOP->op_other;
SV *tmpstr;
- MAGIC *mg = NULL;
- regexp * re;
+ regexp *re = NULL;
/* prevent recompiling under /o and ithreads. */
#if defined(USE_ITHREADS)
if (SvROK(tmpstr)) {
SV * const sv = SvRV(tmpstr);
- if(SvMAGICAL(sv))
- mg = mg_find(sv, PERL_MAGIC_qr);
+ if (SvTYPE(sv) == SVt_REGEXP)
+ re = ((struct xregexp *)SvANY(sv))->xrx_regexp;
}
- if (mg) {
- regexp * const re = reg_temp_copy((regexp *)mg->mg_obj);
+ if (re) {
+ re = reg_temp_copy(re);
ReREFCNT_dec(PM_GETRE(pm));
PM_SETRE(pm, re);
}
SV *e = TOPs; /* e is for 'expression' */
SV *d = TOPm1s; /* d is for 'default', as in PL_defgv */
SV *This, *Other; /* 'This' (and Other to match) to play with C++ */
- MAGIC *mg;
regexp *this_regex, *other_regex;
# define NOT_EMPTY_PROTO(cv) (!SvPOK(cv) || SvCUR(cv) == 0)
&& NOT_EMPTY_PROTO(This) && (Other = d)))
# define SM_REGEX ( \
- (SvROK(d) && SvMAGICAL(This = SvRV(d)) \
- && (mg = mg_find(This, PERL_MAGIC_qr)) \
- && (this_regex = (regexp *)mg->mg_obj) \
+ (SvROK(d) && (SvTYPE(This = SvRV(d)) == SVt_REGEXP) \
+ && (this_regex = ((struct xregexp *)SvANY(This))->xrx_regexp) \
&& (Other = e)) \
|| \
- (SvROK(e) && SvMAGICAL(This = SvRV(e)) \
- && (mg = mg_find(This, PERL_MAGIC_qr)) \
- && (this_regex = (regexp *)mg->mg_obj) \
+ (SvROK(e) && (SvTYPE(This = SvRV(e)) == SVt_REGEXP) \
+ && (this_regex = ((struct xregexp *)SvANY(This))->xrx_regexp) \
&& (Other = d)) )
# define SM_OTHER_REF(type) \
(SvROK(Other) && SvTYPE(SvRV(Other)) == SVt_##type)
-# define SM_OTHER_REGEX (SvROK(Other) && SvMAGICAL(SvRV(Other)) \
- && (mg = mg_find(SvRV(Other), PERL_MAGIC_qr)) \
- && (other_regex = (regexp *)mg->mg_obj))
-
+# define SM_OTHER_REGEX (SvROK(Other) \
+ && (SvTYPE(SvRV(Other)) == SVt_REGEXP) \
+ && (other_regex = ((struct xregexp *)SvANY(SvRV(Other)))->xrx_regexp))
+
# define SM_SEEN_THIS(sv) hv_exists_ent(seen_this, \
sv_2mortal(newSViv(PTR2IV(sv))), 0)
REGEXP * rx = PM_GETRE(pm);
SV * const pkg = CALLREG_PACKAGE(rx);
SV * const rv = sv_newmortal();
- SV * const sv = newSVrv(rv, SvPV_nolen(pkg));
+ SV * const sv = newSVrv(rv, pkg ? SvPV_nolen(pkg) : NULL);
if (rx->extflags & RXf_TAINTED)
SvTAINTED_on(rv);
- sv_upgrade(sv, SVt_ORANGE);
- sv_magic(sv,(SV*)ReREFCNT_inc(rx), PERL_MAGIC_qr,0,0);
+ sv_upgrade(sv, SVt_REGEXP);
+ ((struct xregexp *)SvANY(sv))->xrx_regexp = ReREFCNT_inc(rx);
XPUSHs(rv);
RETURN;
}
Perl_reg_qr_package(pTHX_ REGEXP * const rx)
{
PERL_UNUSED_ARG(rx);
- return newSVpvs("Regexp");
+ return NULL;
}
/* Scans the name of a named buffer from the pattern.
{
/* extract RE object from returned value; compiling if
* necessary */
-
MAGIC *mg = NULL;
- const SV *sv;
- if(SvROK(ret) && SvSMAGICAL(sv = SvRV(ret)))
- mg = mg_find(sv, PERL_MAGIC_qr);
- else if (SvSMAGICAL(ret)) {
+ re = NULL;
+
+ if (SvROK(ret)) {
+ const SV *const sv = SvRV(ret);
+
+ if (SvTYPE(sv) == SVt_REGEXP) {
+ re = ((struct xregexp *)SvANY(sv))->xrx_regexp;
+ } else if (SvSMAGICAL(sv)) {
+ mg = mg_find(sv, PERL_MAGIC_qr);
+ assert(mg);
+ }
+ } else if (SvTYPE(ret) == SVt_REGEXP) {
+ re = ((struct xregexp *)SvANY(ret))->xrx_regexp;
+ } else if (SvSMAGICAL(ret)) {
if (SvGMAGICAL(ret)) {
/* I don't believe that there is ever qr magic
here. */
}
if (mg) {
- re = reg_temp_copy((regexp *)mg->mg_obj); /*XXX:dmq*/
+ re = (regexp *)mg->mg_obj; /*XXX:dmq*/
+ assert(re);
}
+ if (re)
+ re = reg_temp_copy(re);
else {
U32 pm_flags = 0;
const I32 osize = PL_regsize;
{ sizeof(XPVMG), copy_length(XPVMG, xmg_stash), 0, SVt_PVMG, FALSE, HADNV,
HASARENA, FIT_ARENA(0, sizeof(XPVMG)) },
- /* 28 */
- { sizeof(XPVMG), copy_length(XPVMG, xmg_stash), 0, SVt_ORANGE, FALSE, HADNV,
- HASARENA, FIT_ARENA(0, sizeof(XPVMG)) },
+ /* 32 */
+ { sizeof(struct xregexp), copy_length(struct xregexp, xrx_regexp), 0,
+ SVt_REGEXP, FALSE, HADNV, HASARENA, FIT_ARENA(0, sizeof(struct xregexp))
+ },
/* 48 */
{ sizeof(XPVGV), sizeof(XPVGV), 0, SVt_PVGV, TRUE, HADNV,
case SVt_PVGV:
case SVt_PVCV:
case SVt_PVLV:
- case SVt_ORANGE:
+ case SVt_REGEXP:
case SVt_PVMG:
case SVt_PVNV:
case SVt_PV:
STRLEN len;
char *retval;
char *buffer;
- MAGIC *mg;
const SV *const referent = (SV*)SvRV(sv);
if (!referent) {
len = 7;
retval = buffer = savepvn("NULLREF", len);
- } else if (SvTYPE(referent) == SVt_ORANGE
- && ((SvFLAGS(referent) &
- (SVs_OBJECT|SVf_OK|SVs_GMG|SVs_SMG|SVs_RMG))
- == (SVs_OBJECT|SVs_SMG))
- && (mg = mg_find(referent, PERL_MAGIC_qr)))
- {
+ } else if (SvTYPE(referent) == SVt_REGEXP) {
char *str = NULL;
I32 haseval = 0;
U32 flags = 0;
- (str) = CALLREG_AS_STR(mg,lp,&flags,&haseval);
+ struct magic temp;
+ temp.mg_obj
+ = (SV*)((struct xregexp *)SvANY(referent))->xrx_regexp;
+ assert(temp.mg_obj);
+ (str) = CALLREG_AS_STR(&temp,lp,&flags,&haseval);
if (flags & 1)
SvUTF8_on(sv);
else
Safefree(IoFMT_NAME(sv));
Safefree(IoBOTTOM_NAME(sv));
goto freescalar;
+ case SVt_REGEXP:
+ ReREFCNT_dec(((struct xregexp *)SvANY(sv))->xrx_regexp);
+ goto freescalar;
case SVt_PVCV:
case SVt_PVFM:
cv_undef((CV*)sv);
case SVt_PVFM: return "FORMAT";
case SVt_PVIO: return "IO";
case SVt_BIND: return "BIND";
- case SVt_ORANGE: return "ORANGE";
+ case SVt_REGEXP: return "Regexp"; /* FIXME? to "REGEXP" */
default: return "UNKNOWN";
}
}
case SVt_PVAV:
case SVt_PVCV:
case SVt_PVLV:
- case SVt_ORANGE:
+ case SVt_REGEXP:
case SVt_PVMG:
case SVt_PVNV:
case SVt_PVIV:
break;
case SVt_PVMG:
break;
- case SVt_ORANGE:
+ case SVt_REGEXP:
+ ((struct xregexp *)SvANY(dstr))->xrx_regexp
+ = CALLREGDUPE(((struct xregexp *)SvANY(dstr))->xrx_regexp,
+ param);
break;
case SVt_PVLV:
/* XXX LvTARGOFF sometimes holds PMOP* when DEBUGGING */
SVt_PVIV, /* 5 */
SVt_PVNV, /* 6 */
SVt_PVMG, /* 7 */
- SVt_ORANGE, /* 8 */
+ SVt_REGEXP, /* 8 */
/* PVBM was here, before BIND replaced it. */
SVt_PVGV, /* 9 */
SVt_PVLV, /* 10 */
HV* xmg_stash; /* class package */
};
+struct xregexp {
+ union {
+ NV xnv_nv; /* numeric value, if any */
+ HV * xgv_stash;
+ struct {
+ U32 xlow;
+ U32 xhigh;
+ } xpad_cop_seq; /* used by pad.c for cop_sequence */
+ struct {
+ U32 xbm_previous; /* how many characters in string before rare? */
+ U8 xbm_flags;
+ U8 xbm_rare; /* rarest character in string */
+ } xbm_s; /* fields from PVBM */
+ } xnv_u;
+ STRLEN xpv_cur; /* length of svu_pv as a C string */
+ STRLEN xpv_len; /* allocated size */
+ union {
+ IV xivu_iv; /* integer value or pv offset */
+ UV xivu_uv;
+ void * xivu_p1;
+ I32 xivu_i32;
+ HEK * xivu_namehek;
+ } xiv_u;
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
+ HV* xmg_stash; /* class package */
+ REGEXP * xrx_regexp; /* Our regular expression */
+};
+
struct xpvlv {
union {
NV xnv_nv; /* numeric value, if any */
require './test.pl';
}
-plan tests => 2;
+plan tests => 1;
my $rx = qr//;
is(ref $rx, "Regexp", "qr// blessed into `Regexp' by default");
-
-#
-# DESTROY doesn't do anything in the case of qr// except make sure
-# that lookups for it don't end up in AUTOLOAD lookups. But make sure
-# it's there anyway.
-#
-ok($rx->can("DESTROY"), "DESTROY method defined for Regexp");
XS(XS_Internals_SvREFCNT);
XS(XS_Internals_hv_clear_placehold);
XS(XS_PerlIO_get_layers);
-XS(XS_Regexp_DESTROY);
XS(XS_Internals_hash_seed);
XS(XS_Internals_rehash_seed);
XS(XS_Internals_HvREHASH);
XS_Internals_hv_clear_placehold, file, "\\%");
newXSproto("PerlIO::get_layers",
XS_PerlIO_get_layers, file, "*;@");
- newXS("Regexp::DESTROY", XS_Regexp_DESTROY, file);
newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
}
}
-XS(XS_Regexp_DESTROY)
-{
- PERL_UNUSED_CONTEXT;
- PERL_UNUSED_ARG(cv);
-}
-
XS(XS_PerlIO_get_layers)
{
dVAR;
REGEXP *
Perl_get_re_arg(pTHX_ SV *sv) {
SV *tmpsv;
- MAGIC *mg;
if (sv) {
if (SvMAGICAL(sv))
mg_get(sv);
if (SvROK(sv) &&
(tmpsv = (SV*)SvRV(sv)) && /* assign deliberate */
- SvTYPE(tmpsv) == SVt_ORANGE &&
- (mg = mg_find(tmpsv, PERL_MAGIC_qr))) /* assign deliberate */
+ SvTYPE(tmpsv) == SVt_REGEXP)
{
- return (REGEXP *)mg->mg_obj;
+ return ((struct xregexp *)SvANY(tmpsv))->xrx_regexp;
}
}