#include "EXTERN.h"
#include "perl.h"
-static void doencodes _((SV *sv, char *s, I32 len));
+/*
+ * Types used in bitwise operations.
+ *
+ * Normally we'd just use IV and UV. However, some hardware and
+ * software combinations (e.g. Alpha and current OSF/1) don't have a
+ * floating-point type to use for NV that has adequate bits to fully
+ * hold an IV/UV. (In other words, sizeof(long) == sizeof(double).)
+ *
+ * It just so happens that "int" is the right size everywhere, at
+ * least today.
+ */
+typedef int IBW;
+typedef unsigned UBW;
+
+static void doencodes _((SV* sv, char* s, I32 len));
+static SV* refto _((SV* sv));
+static U32 seed _((void));
+
+static bool srand_called = FALSE;
/* variations on pp_null */
sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVGV);
}
}
- if (op->op_private & OPpLVAL_INTRO) {
- GP *ogp = GvGP(sv);
-
- SSCHECK(3);
- SSPUSHPTR(SvREFCNT_inc(sv));
- SSPUSHPTR(ogp);
- SSPUSHINT(SAVEt_GP);
-
- if (op->op_flags & OPf_SPECIAL) {
- GvGP(sv)->gp_refcnt++; /* will soon be assigned */
- GvINTRO_on(sv);
- }
- else {
- GP *gp;
- Newz(602,gp, 1, GP);
- GvGP(sv) = gp;
- GvREFCNT(sv) = 1;
- GvSV(sv) = NEWSV(72,0);
- GvLINE(sv) = curcop->cop_line;
- GvEGV(sv) = (GV*)sv;
- }
- }
+ if (op->op_private & OPpLVAL_INTRO)
+ save_gp((GV*)sv, !(op->op_flags & OPf_SPECIAL));
SETs(sv);
RETURN;
}
if (op->op_flags & OPf_MOD) {
if (op->op_private & OPpLVAL_INTRO)
sv = save_scalar((GV*)TOPs);
- else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+ else if (op->op_private & OPpDEREF)
provide_ref(op, sv);
}
SETs(sv);
dSP; dTARGET; dPOPss;
if (op->op_flags & OPf_MOD) {
- LvTYPE(TARG) = '<';
+ if (SvTYPE(TARG) < SVt_PVLV) {
+ sv_upgrade(TARG, SVt_PVLV);
+ sv_magic(TARG, Nullsv, '.', Nullch, 0);
+ }
+
+ LvTYPE(TARG) = '.';
LvTARG(TARG) = sv;
PUSHs(TARG); /* no SvSETMAGIC */
RETURN;
/* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
/* (But not in defined().) */
CV *cv = sv_2cv(TOPs, &stash, &gv, !(op->op_flags & OPf_SPECIAL));
-
- if (!cv)
+ if (cv) {
+ if (CvCLONE(cv))
+ cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
+ }
+ else
cv = (CV*)&sv_undef;
SETs((SV*)cv);
RETURN;
ret = &sv_undef;
cv = sv_2cv(TOPs, &stash, &gv, FALSE);
- if (cv && SvPOK(cv)) {
- char *p = SvPVX(cv);
- ret = sv_2mortal(newSVpv(p ? p : "", SvLEN(cv)));
- }
+ if (cv && SvPOK(cv))
+ ret = sv_2mortal(newSVpv(SvPVX(cv), SvCUR(cv)));
SETs(ret);
RETURN;
}
PP(pp_anoncode)
{
dSP;
- CV* cv = (CV*)cSVOP->op_sv;
- EXTEND(SP,1);
-
+ CV* cv = (CV*)curpad[op->op_targ];
if (CvCLONE(cv))
cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
-
+ EXTEND(SP,1);
PUSHs((SV*)cv);
RETURN;
}
PP(pp_srefgen)
{
- dSP; dTOPss;
- SV* rv;
- rv = sv_newmortal();
- sv_upgrade(rv, SVt_RV);
- if (SvPADTMP(sv))
- sv = newSVsv(sv);
- else {
- SvTEMP_off(sv);
- (void)SvREFCNT_inc(sv);
- }
- SvRV(rv) = sv;
- SvROK_on(rv);
- SETs(rv);
+ dSP;
+ *SP = refto(*SP);
RETURN;
}
PP(pp_refgen)
{
dSP; dMARK;
- SV* sv;
- SV* rv;
if (GIMME != G_ARRAY) {
MARK[1] = *SP;
SP = MARK + 1;
}
EXTEND_MORTAL(SP - MARK);
- while (MARK < SP) {
- sv = *++MARK;
- rv = sv_newmortal();
- sv_upgrade(rv, SVt_RV);
- if (SvPADTMP(sv))
- sv = newSVsv(sv);
- else {
- SvTEMP_off(sv);
- (void)SvREFCNT_inc(sv);
- }
- SvRV(rv) = sv;
- SvROK_on(rv);
- *MARK = rv;
- }
+ while (++MARK <= SP)
+ *MARK = refto(*MARK);
RETURN;
}
+static SV*
+refto(sv)
+SV* sv;
+{
+ SV* rv;
+
+ if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') {
+ if (LvTARGLEN(sv))
+ vivify_itervar(sv);
+ if (LvTARG(sv))
+ sv = LvTARG(sv);
+ }
+ else if (SvPADTMP(sv))
+ sv = newSVsv(sv);
+ else {
+ SvTEMP_off(sv);
+ (void)SvREFCNT_inc(sv);
+ }
+ rv = sv_newmortal();
+ sv_upgrade(rv, SVt_RV);
+ SvRV(rv) = sv;
+ SvROK_on(rv);
+ return rv;
+}
+
PP(pp_ref)
{
dSP; dTARGET;
dSP;
SV *sv;
- if (!op->op_private)
+ if (!op->op_private) {
+ EXTEND(SP, 1);
RETPUSHUNDEF;
+ }
sv = POPs;
if (!sv)
break;
case SVt_PVCV:
cv_undef((CV*)sv);
- sub_generation++;
break;
case SVt_PVGV:
- if (SvFAKE(sv)) {
- sv_setsv(sv, &sv_undef);
- break;
- }
+ if (SvFAKE(sv))
+ sv_setsv(sv, &sv_undef);
+ break;
default:
if (SvPOK(sv) && SvLEN(sv)) {
(void)SvOOK_off(sv);
PP(pp_predec)
{
dSP;
+ if (SvREADONLY(TOPs))
+ croak(no_modify);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MIN)
{
PP(pp_postinc)
{
dSP; dTARGET;
+ if (SvREADONLY(TOPs))
+ croak(no_modify);
sv_setsv(TARG, TOPs);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MAX)
PP(pp_postdec)
{
dSP; dTARGET;
+ if(SvREADONLY(TOPs))
+ croak(no_modify);
sv_setsv(TARG, TOPs);
if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) &&
SvIVX(TOPs) != IV_MIN)
{
dSP; dATARGET; tryAMAGICbin(div,opASSIGN);
{
- dPOPnv;
- if (value == 0.0)
+ dPOPPOPnnrl;
+ double value;
+ if (right == 0.0)
DIE("Illegal division by zero");
#ifdef SLOPPYDIVIDE
/* insure that 20./5. == 4. */
{
- double x;
- I32 k;
- x = POPn;
- if ((double)I_32(x) == x &&
- (double)I_32(value) == value &&
- (k = I_32(x)/I_32(value))*I_32(value) == I_32(x)) {
+ IV k;
+ if ((double)I_V(left) == left &&
+ (double)I_V(right) == right &&
+ (k = I_V(left)/I_V(right))*I_V(right) == I_V(left)) {
value = k;
} else {
- value = x/value;
+ value = left / right;
}
}
#else
- value = POPn / value;
+ value = left / right;
#endif
PUSHn( value );
RETURN;
{
dSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
{
- register IV value;
- register UV uval;
+ register UV right;
- uval = POPn;
- if (!uval)
+ right = POPu;
+ if (!right)
DIE("Illegal modulus zero");
- value = TOPn;
- if (value >= 0)
- value = (UV)value % uval;
+
+ if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) {
+ register IV left = SvIVX(TOPs);
+ if (left < 0)
+ SETu( (right - ((UV)(-left) - 1) % right) - 1 );
+ else
+ SETi( left % right );
+ }
else {
- value = (uval - ((UV)(-value - 1) % uval)) - 1;
+ register double left = TOPn;
+ if (left < 0.0)
+ SETu( (right - (U_V(-left) - 1) % right) - 1 );
+ else
+ SETu( U_V(left) % right );
}
- SETi(value);
RETURN;
}
}
}
SvSetSV(TARG, tmpstr);
SvPV_force(TARG, len);
- if (count >= 1) {
- SvGROW(TARG, (count * len) + 1);
- if (count > 1)
+ if (count != 1) {
+ if (count < 1)
+ SvCUR_set(TARG, 0);
+ else {
+ SvGROW(TARG, (count * len) + 1);
repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
- SvCUR(TARG) *= count;
+ SvCUR(TARG) *= count;
+ }
*SvEND(TARG) = '\0';
- (void)SvPOK_only(TARG);
}
- else
- sv_setsv(TARG, &sv_no);
+ (void)SvPOK_only(TARG);
PUSHTARG;
}
RETURN;
{
dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN);
{
- dPOPTOPnnrl;
+ dPOPTOPnnrl_ul;
SETn( left - right );
RETURN;
}
{
dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN);
{
- IV shift = POPi;
+ IBW shift = POPi;
if (op->op_private & HINT_INTEGER) {
- IV i = TOPi;
+ IBW i = TOPi;
SETi( i << shift );
}
else {
- UV u = TOPu;
+ UBW u = TOPu;
SETu( u << shift );
}
RETURN;
{
dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN);
{
- IV shift = POPi;
+ IBW shift = POPi;
if (op->op_private & HINT_INTEGER) {
- IV i = TOPi;
+ IBW i = TOPi;
SETi( i >> shift );
}
else {
- UV u = TOPu;
+ UBW u = TOPu;
SETu( u >> shift );
}
RETURN;
dPOPTOPnnrl;
I32 value;
- if (left > right)
- value = 1;
+ if (left == right)
+ value = 0;
else if (left < right)
value = -1;
- else
- value = 0;
+ else if (left > right)
+ value = 1;
+ else {
+ SETs(&sv_undef);
+ RETURN;
+ }
SETi(value);
RETURN;
}
}
}
+PP(pp_seq)
+{
+ dSP; tryAMAGICbinSET(seq,0);
+ {
+ dPOPTOPssrl;
+ SETs( sv_eq(left, right) ? &sv_yes : &sv_no );
+ RETURN;
+ }
+}
+
PP(pp_sne)
{
dSP; tryAMAGICbinSET(sne,0);
{
dPOPTOPssrl;
- bool ne = ((op->op_private & OPpLOCALE)
- ? (sv_cmp_locale(left, right) != 0)
- : !sv_eq(left, right));
- SETs( ne ? &sv_yes : &sv_no );
+ SETs( !sv_eq(left, right) ? &sv_yes : &sv_no );
RETURN;
}
}
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
- UV value = SvUV(left) & SvUV(right);
- if (op->op_private & HINT_INTEGER)
- SETi( (IV)value );
- else
+ if (op->op_private & HINT_INTEGER) {
+ IBW value = SvIV(left) & SvIV(right);
+ SETi( value );
+ }
+ else {
+ UBW value = SvUV(left) & SvUV(right);
SETu( value );
+ }
}
else {
do_vop(op->op_type, TARG, left, right);
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
- UV value = SvUV(left) ^ SvUV(right);
- if (op->op_private & HINT_INTEGER)
- SETi( (IV)value );
- else
+ if (op->op_private & HINT_INTEGER) {
+ IBW value = (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right);
+ SETi( value );
+ }
+ else {
+ UBW value = (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right);
SETu( value );
+ }
}
else {
do_vop(op->op_type, TARG, left, right);
{
dPOPTOPssrl;
if (SvNIOKp(left) || SvNIOKp(right)) {
- UV value = SvUV(left) | SvUV(right);
- if (op->op_private & HINT_INTEGER)
- SETi( (IV)value );
- else
+ if (op->op_private & HINT_INTEGER) {
+ IBW value = (USE_LEFT(left) ? SvIV(left) : 0) | SvIV(right);
+ SETi( value );
+ }
+ else {
+ UBW value = (USE_LEFT(left) ? SvUV(left) : 0) | SvUV(right);
SETu( value );
+ }
}
else {
do_vop(op->op_type, TARG, left, right);
{
dTOPss;
if (SvNIOKp(sv)) {
- UV value = ~SvUV(sv);
- if (op->op_private & HINT_INTEGER)
- SETi( (IV)value );
- else
+ if (op->op_private & HINT_INTEGER) {
+ IBW value = ~SvIV(sv);
+ SETi( value );
+ }
+ else {
+ UBW value = ~SvUV(sv);
SETu( value );
+ }
}
else {
register char *tmps;
dSP; dATARGET; tryAMAGICbin(mod,opASSIGN);
{
dPOPTOPiirl;
+ if (!right)
+ DIE("Illegal modulus zero");
SETi( left % right );
RETURN;
}
value = POPn;
if (value == 0.0)
value = 1.0;
+ if (!srand_called) {
+ (void)srand((unsigned)seed());
+ srand_called = TRUE;
+ }
#if RANDBITS == 31
value = rand() * value / 2147483648.0;
#else
PP(pp_srand)
{
dSP;
- I32 anum;
+ UV anum;
+ if (MAXARG < 1)
+ anum = seed();
+ else
+ anum = POPu;
+ (void)srand((unsigned)anum);
+ srand_called = TRUE;
+ EXTEND(SP, 1);
+ RETPUSHYES;
+}
- if (MAXARG < 1) {
+static U32
+seed()
+{
+ U32 u;
#ifdef VMS
# include <starlet.h>
- unsigned int when[2];
- _ckvmssts(sys$gettim(when));
- anum = when[0] ^ when[1];
+ unsigned int when[2];
+ _ckvmssts(sys$gettim(when));
+ u = when[0] ^ when[1];
#else
-# if defined(I_SYS_TIME) && !defined(PLAN9)
- struct timeval when;
- gettimeofday(&when,(struct timezone *) 0);
- anum = when.tv_sec ^ when.tv_usec;
+# ifdef HAS_GETTIMEOFDAY
+ struct timeval when;
+ gettimeofday(&when,(struct timezone *) 0);
+ u = when.tv_sec ^ when.tv_usec;
# else
- Time_t when;
- (void)time(&when);
- anum = when;
+ Time_t when;
+ (void)time(&when);
+ u = when;
# endif
#endif
-#if !defined(PLAN9) /* XXX Plan9 assembler chokes on this; fix coming soon */
- /* 17-Jul-1996 bailey@genetics.upenn.edu */
- /* What is a good hashing algorithm here? */
- anum ^= ( ( 269 * (U32)getpid())
- ^ (26107 * (U32)&when)
- ^ (73819 * (U32)stack_sp));
+#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */
+ /* What is a good hashing algorithm here? */
+ u ^= ( ( 269 * (U32)getpid())
+ ^ (26107 * (U32)&when)
+ ^ (73819 * (U32)stack_sp));
#endif
- }
- else
- anum = POPi;
- (void)srand(anum);
- EXTEND(SP, 1);
- RETPUSHYES;
+ return u;
}
PP(pp_exp)
double value;
value = POPn;
if (value <= 0.0) {
- NUMERIC_STANDARD();
+ SET_NUMERIC_STANDARD();
DIE("Can't take log of %g", value);
}
value = log(value);
double value;
value = POPn;
if (value < 0.0) {
- NUMERIC_STANDARD();
+ SET_NUMERIC_STANDARD();
DIE("Can't take sqrt of %g", value);
}
value = sqrt(value);
PP(pp_int)
{
dSP; dTARGET;
- double value;
- value = POPn;
- if (value >= 0.0)
- (void)modf(value, &value);
- else {
- (void)modf(-value, &value);
- value = -value;
+ {
+ double value = TOPn;
+ IV iv;
+
+ if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs)) {
+ iv = SvIVX(TOPs);
+ SETi(iv);
+ }
+ else {
+ if (value >= 0.0)
+ (void)modf(value, &value);
+ else {
+ (void)modf(-value, &value);
+ value = -value;
+ }
+ iv = I_V(value);
+ if (iv == value)
+ SETi(iv);
+ else
+ SETn(value);
+ }
}
- XPUSHn(value);
RETURN;
}
{
dSP; dTARGET; tryAMAGICun(abs);
{
- double value;
- value = POPn;
-
- if (value < 0.0)
- value = -value;
-
- XPUSHn(value);
- RETURN;
+ double value = TOPn;
+ IV iv;
+
+ if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs) &&
+ (iv = SvIVX(TOPs)) != IV_MIN) {
+ if (iv < 0)
+ iv = -iv;
+ SETi(iv);
+ }
+ else {
+ if (value < 0.0)
+ value = -value;
+ SETn(value);
+ }
}
+ RETURN;
}
PP(pp_hex)
else
sv_setpvn(sv,"",0); /* avoid lexical reincarnation */
}
+
if (SvTYPE(TARG) < SVt_PVLV) {
sv_upgrade(TARG, SVt_PVLV);
sv_magic(TARG, Nullsv, 'x', Nullch, 0);
}
- LvTYPE(TARG) = 's';
+ LvTYPE(TARG) = 'x';
LvTARG(TARG) = sv;
LvTARGOFF(TARG) = pos;
LvTARGLEN(TARG) = rem;
PP(pp_sprintf)
{
dSP; dMARK; dORIGMARK; dTARGET;
-#ifdef LC_NUMERIC
+#ifdef USE_LOCALE_NUMERIC
if (op->op_private & OPpLOCALE)
- NUMERIC_LOCAL();
+ SET_NUMERIC_LOCAL();
else
- NUMERIC_STANDARD();
-#endif /* LC_NUMERIC */
+ SET_NUMERIC_STANDARD();
+#endif
do_sprintf(TARG, SP-MARK, MARK+1);
TAINT_IF(SvTAINTED(TARG));
SP = ORIGMARK;
{
dSP;
SV *sv;
- SV *tmpsv = POPs;
- HV *hv = (HV*)POPs;
- STRLEN len;
- if (SvTYPE(hv) != SVt_PVHV) {
- DIE("Not a HASH reference");
+ HV *hv;
+
+ if (op->op_private & OPpSLICE) {
+ dMARK; dORIGMARK;
+ hv = (HV*)POPs;
+ if (SvTYPE(hv) != SVt_PVHV)
+ DIE("Not a HASH reference");
+ while (++MARK <= SP) {
+ sv = hv_delete_ent(hv, *MARK,
+ (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
+ *MARK = sv ? sv : &sv_undef;
+ }
+ if (GIMME != G_ARRAY) {
+ MARK = ORIGMARK;
+ *++MARK = *SP;
+ SP = MARK;
+ }
+ }
+ else {
+ SV *keysv = POPs;
+ hv = (HV*)POPs;
+ if (SvTYPE(hv) != SVt_PVHV)
+ DIE("Not a HASH reference");
+ sv = hv_delete_ent(hv, keysv,
+ (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
+ if (!sv)
+ sv = &sv_undef;
+ PUSHs(sv);
}
- sv = hv_delete_ent(hv, tmpsv,
- (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0);
- if (!sv)
- RETPUSHUNDEF;
- PUSHs(sv);
RETURN;
}
if (ix >= max || !(*lelem = firstrelem[ix]))
*lelem = &sv_undef;
}
- if (!is_something_there && (SvOKp(*lelem) || SvGMAGICAL(*lelem)))
+ if (!is_something_there && (SvOK(*lelem) || SvGMAGICAL(*lelem)))
is_something_there = TRUE;
}
if (is_something_there)
PP(pp_anonlist)
{
- dSP; dMARK;
+ dSP; dMARK; dORIGMARK;
I32 items = SP - MARK;
- SP = MARK;
- XPUSHs((SV*)sv_2mortal((SV*)av_make(items, MARK+1)));
+ SV *av = sv_2mortal((SV*)av_make(items, MARK+1));
+ SP = ORIGMARK; /* av_make() might realloc stack_sp */
+ XPUSHs(av);
RETURN;
}
PP(pp_anonhash)
{
dSP; dMARK; dORIGMARK;
- STRLEN len;
HV* hv = (HV*)sv_2mortal((SV*)newHV());
while (MARK < SP) {
Copy(AvARRAY(ary)+offset, MARK, length, SV*);
if (AvREAL(ary)) {
EXTEND_MORTAL(length);
- for (i = length, dst = MARK; i; i--)
- sv_2mortal(*dst++); /* free them eventualy */
+ for (i = length, dst = MARK; i; i--) {
+ if (!SvIMMORTAL(*dst))
+ sv_2mortal(*dst); /* free them eventualy */
+ dst++;
+ }
}
MARK += length - 1;
}
else {
*MARK = AvARRAY(ary)[offset+length-1];
if (AvREAL(ary)) {
- sv_2mortal(*MARK);
+ if (!SvIMMORTAL(*MARK))
+ sv_2mortal(*MARK);
for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
SvREFCNT_dec(*dst++); /* free them now */
}
Copy(tmparyval, MARK, length, SV*);
if (AvREAL(ary)) {
EXTEND_MORTAL(length);
- for (i = length, dst = MARK; i; i--)
- sv_2mortal(*dst++); /* free them eventualy */
+ for (i = length, dst = MARK; i; i--) {
+ if (!SvIMMORTAL(*dst))
+ sv_2mortal(*dst); /* free them eventualy */
+ dst++;
+ }
}
Safefree(tmparyval);
}
else if (length--) {
*MARK = tmparyval[length];
if (AvREAL(ary)) {
- sv_2mortal(*MARK);
+ if (!SvIMMORTAL(*MARK))
+ sv_2mortal(*MARK);
while (length-- > 0)
SvREFCNT_dec(tmparyval[length]);
}
dSP;
AV *av = (AV*)POPs;
SV *sv = av_pop(av);
- if (sv != &sv_undef && AvREAL(av))
+ if (!SvIMMORTAL(sv) && AvREAL(av))
(void)sv_2mortal(sv);
PUSHs(sv);
RETURN;
EXTEND(SP, 1);
if (!sv)
RETPUSHUNDEF;
- if (sv != &sv_undef && AvREAL(av))
+ if (!SvIMMORTAL(sv) && AvREAL(av))
(void)sv_2mortal(sv);
PUSHs(sv);
RETURN;
{
dSP;
dPOPPOPssrl;
+ SV **oldsp = sp;
SV *sv;
STRLEN llen;
STRLEN rlen;
checksum = 0;
}
}
+ if (sp == oldsp && GIMME != G_ARRAY)
+ PUSHs(&sv_undef);
RETURN;
}
*--in = div128(norm, &done) | 0x80;
result[len - 1] &= 0x7F; /* clear continue bit */
sv_catpvn(cat, in, (result + len) - in);
+ Safefree(result);
SvREFCNT_dec(norm); /* free norm */
}
else if (SvNOKp(fromstr)) {
STRLEN len;
register char *s = SvPV(sv, len);
char *strend = s + len;
- register PMOP *pm = (PMOP*)POPs;
+ register PMOP *pm;
+ register REGEXP *rx;
register SV *dstr;
register char *m;
I32 iters = 0;
I32 realarray = 0;
I32 base;
AV *oldstack = curstack;
- register REGEXP *rx = pm->op_pmregexp;
I32 gimme = GIMME;
I32 oldsave = savestack_ix;
+#ifdef DEBUGGING
+ Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*);
+#else
+ pm = (PMOP*)POPs;
+#endif
if (!pm || !s)
DIE("panic: do_split");
+ rx = pm->op_pmregexp;
TAINT_IF((pm->op_pmflags & PMf_LOCALE) &&
(pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE)));
s = m;
}
}
- else if (pm->op_pmshort) {
+ else if (pm->op_pmshort && !rx->nparens) {
i = SvCUR(pm->op_pmshort);
if (i == 1) {
i = *SvPVX(pm->op_pmshort);