summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opcode.h7
-rw-r--r--pp.c32
-rw-r--r--pp_proto.h1
-rwxr-xr-xregen/opcode.pl3
4 files changed, 12 insertions, 31 deletions
diff --git a/opcode.h b/opcode.h
index ce93bf3b15..0d0990e4e1 100644
--- a/opcode.h
+++ b/opcode.h
@@ -25,7 +25,8 @@
#define Perl_pp_predec Perl_pp_preinc
#define Perl_pp_i_predec Perl_pp_preinc
#define Perl_pp_i_postinc Perl_pp_postinc
-#define Perl_pp_i_postdec Perl_pp_postdec
+#define Perl_pp_postdec Perl_pp_postinc
+#define Perl_pp_i_postdec Perl_pp_postinc
#define Perl_pp_slt Perl_pp_sle
#define Perl_pp_sgt Perl_pp_sle
#define Perl_pp_sge Perl_pp_sle
@@ -972,8 +973,8 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */
Perl_pp_i_predec, /* implemented by Perl_pp_preinc */
Perl_pp_postinc,
Perl_pp_i_postinc, /* implemented by Perl_pp_postinc */
- Perl_pp_postdec,
- Perl_pp_i_postdec, /* implemented by Perl_pp_postdec */
+ Perl_pp_postdec, /* implemented by Perl_pp_postinc */
+ Perl_pp_i_postdec, /* implemented by Perl_pp_postinc */
Perl_pp_pow,
Perl_pp_multiply,
Perl_pp_i_multiply,
diff --git a/pp.c b/pp.c
index 59d318a5e3..48774bdab6 100644
--- a/pp.c
+++ b/pp.c
@@ -1054,48 +1054,30 @@ PP(pp_undef)
PP(pp_postinc)
{
dVAR; dSP; dTARGET;
+ const bool inc =
+ PL_op->op_type == OP_POSTINC || PL_op->op_type == OP_I_POSTINC;
if (SvTYPE(TOPs) >= SVt_PVAV || (isGV_with_GP(TOPs) && !SvFAKE(TOPs)))
Perl_croak_no_modify(aTHX);
if (SvROK(TOPs))
TARG = sv_newmortal();
sv_setsv(TARG, TOPs);
if (!SvREADONLY(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)
- && SvIVX(TOPs) != IV_MAX)
+ && SvIVX(TOPs) != (inc ? IV_MAX : IV_MIN))
{
- SvIV_set(TOPs, SvIVX(TOPs) + 1);
+ SvIV_set(TOPs, SvIVX(TOPs) + (inc ? 1 : -1));
SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
}
- else
+ else if (inc)
sv_inc_nomg(TOPs);
+ else sv_dec_nomg(TOPs);
SvSETMAGIC(TOPs);
/* special case for undef: see thread at 2003-03/msg00536.html in archive */
- if (!SvOK(TARG))
+ if (inc && !SvOK(TARG))
sv_setiv(TARG, 0);
SETs(TARG);
return NORMAL;
}
-PP(pp_postdec)
-{
- dVAR; dSP; dTARGET;
- if (SvTYPE(TOPs) >= SVt_PVAV || (isGV_with_GP(TOPs) && !SvFAKE(TOPs)))
- Perl_croak_no_modify(aTHX);
- if (SvROK(TOPs))
- TARG = sv_newmortal();
- sv_setsv(TARG, TOPs);
- if (!SvREADONLY(TOPs) && SvIOK_notUV(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)
- && SvIVX(TOPs) != IV_MIN)
- {
- SvIV_set(TOPs, SvIVX(TOPs) - 1);
- SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK);
- }
- else
- sv_dec_nomg(TOPs);
- SvSETMAGIC(TOPs);
- SETs(TARG);
- return NORMAL;
-}
-
/* Ordinary operators. */
PP(pp_pow)
diff --git a/pp_proto.h b/pp_proto.h
index e795c8ad51..bc4622b2cc 100644
--- a/pp_proto.h
+++ b/pp_proto.h
@@ -167,7 +167,6 @@ PERL_CALLCONV OP *Perl_pp_padhv(pTHX);
PERL_CALLCONV OP *Perl_pp_padsv(pTHX);
PERL_CALLCONV OP *Perl_pp_pipe_op(pTHX);
PERL_CALLCONV OP *Perl_pp_pos(pTHX);
-PERL_CALLCONV OP *Perl_pp_postdec(pTHX);
PERL_CALLCONV OP *Perl_pp_postinc(pTHX);
PERL_CALLCONV OP *Perl_pp_pow(pTHX);
PERL_CALLCONV OP *Perl_pp_preinc(pTHX);
diff --git a/regen/opcode.pl b/regen/opcode.pl
index 5c81ec37d7..d8186cd294 100755
--- a/regen/opcode.pl
+++ b/regen/opcode.pl
@@ -117,8 +117,7 @@ my @raw_alias = (
Perl_pp_schop => [qw(schop schomp)],
Perl_pp_bind => {connect => '#ifdef HAS_SOCKET'},
Perl_pp_preinc => ['i_preinc', 'predec', 'i_predec'],
- Perl_pp_postinc => ['i_postinc'],
- Perl_pp_postdec => ['i_postdec'],
+ Perl_pp_postinc => ['i_postinc', 'postdec', 'i_postdec'],
Perl_pp_ehostent => [qw(enetent eprotoent eservent
spwent epwent sgrent egrent)],
Perl_pp_shostent => [qw(snetent sprotoent sservent)],