Skip to content

Commit

Permalink
Squash repetitive code in pp.c:S_delete_local
Browse files Browse the repository at this point in the history
The two branches of this were almost identical.  Not only is it unnec-
essary to repeat the code, but it is error-prone, as bug fixes have to
be done in both branches.
  • Loading branch information
Father Chrysostomos committed Jun 27, 2012
1 parent be6064f commit ca3f996
Showing 1 changed file with 23 additions and 89 deletions.
112 changes: 23 additions & 89 deletions pp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4425,17 +4425,21 @@ S_do_delete_local(pTHX)
const I32 gimme = GIMME_V;
const MAGIC *mg;
HV *stash;

if (PL_op->op_private & OPpSLICE) {
dMARK; dORIGMARK;
SV * const osv = POPs;
const bool tied = SvRMAGICAL(osv)
const bool sliced = !!(PL_op->op_private & OPpSLICE);
SV *unsliced_keysv = sliced ? NULL : POPs;
SV * const osv = POPs;
register SV **mark =
sliced ? PL_stack_base + POPMARK : &unsliced_keysv-1;
dORIGMARK;
const bool tied = SvRMAGICAL(osv)
&& mg_find((const SV *)osv, PERL_MAGIC_tied);
const bool can_preserve = SvCANEXISTDELETE(osv);
const U32 type = SvTYPE(osv);
if (type == SVt_PVHV) { /* hash element */
const bool can_preserve = SvCANEXISTDELETE(osv);
const U32 type = SvTYPE(osv);
SV ** const end = sliced ? SP : &unsliced_keysv;

if (type == SVt_PVHV) { /* hash element */
HV * const hv = MUTABLE_HV(osv);
while (++MARK <= SP) {
while (++MARK <= end) {
SV * const keysv = *MARK;
SV *sv = NULL;
bool preeminent = TRUE;
Expand Down Expand Up @@ -4466,11 +4470,11 @@ S_do_delete_local(pTHX)
*MARK = &PL_sv_undef;
}
}
}
else if (type == SVt_PVAV) { /* array element */
}
else if (type == SVt_PVAV) { /* array element */
if (PL_op->op_flags & OPf_SPECIAL) {
AV * const av = MUTABLE_AV(osv);
while (++MARK <= SP) {
while (++MARK <= end) {
I32 idx = SvIV(*MARK);
SV *sv = NULL;
bool preeminent = TRUE;
Expand Down Expand Up @@ -4501,9 +4505,12 @@ S_do_delete_local(pTHX)
}
}
}
}
else
else
DIE(aTHX_ "panic: avhv_delete no longer supported");
}
else
DIE(aTHX_ "Not a HASH reference");
if (sliced) {
if (gimme == G_VOID)
SP = ORIGMARK;
else if (gimme == G_SCALAR) {
Expand All @@ -4515,81 +4522,8 @@ S_do_delete_local(pTHX)
SP = MARK;
}
}
else {
SV * const keysv = POPs;
SV * const osv = POPs;
const bool tied = SvRMAGICAL(osv)
&& mg_find((const SV *)osv, PERL_MAGIC_tied);
const bool can_preserve = SvCANEXISTDELETE(osv);
const U32 type = SvTYPE(osv);
SV *sv = NULL;
if (type == SVt_PVHV) {
HV * const hv = MUTABLE_HV(osv);
bool preeminent = TRUE;
if (can_preserve)
preeminent = hv_exists_ent(hv, keysv, 0);
if (tied) {
HE *he = hv_fetch_ent(hv, keysv, 1, 0);
if (he)
sv = HeVAL(he);
else
preeminent = FALSE;
}
else {
sv = hv_delete_ent(hv, keysv, 0, 0);
SvREFCNT_inc_simple_void(sv); /* De-mortalize */
}
if (preeminent) {
if (!sv) DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
save_helem_flags(hv, keysv, &sv, SAVEf_KEEPOLDELEM);
if (tied) {
SV *nsv = sv_mortalcopy(sv);
mg_clear(sv);
sv = nsv;
}
}
else
SAVEHDELETE(hv, keysv);
}
else if (type == SVt_PVAV) {
if (PL_op->op_flags & OPf_SPECIAL) {
AV * const av = MUTABLE_AV(osv);
I32 idx = SvIV(keysv);
bool preeminent = TRUE;
if (can_preserve)
preeminent = av_exists(av, idx);
if (tied) {
SV **svp = av_fetch(av, idx, 1);
if (svp)
sv = *svp;
else
preeminent = FALSE;
}
else {
sv = av_delete(av, idx, 0);
SvREFCNT_inc_simple_void(sv); /* De-mortalize */
}
if (preeminent) {
save_aelem_flags(av, idx, &sv, SAVEf_KEEPOLDELEM);
if (tied) {
SV *nsv = sv_mortalcopy(sv);
mg_clear(sv);
sv = nsv;
}
}
else
SAVEADELETE(av, idx);
}
else
DIE(aTHX_ "panic: avhv_delete no longer supported");
}
else
DIE(aTHX_ "Not a HASH reference");
if (!sv)
sv = &PL_sv_undef;
if (gimme != G_VOID)
PUSHs(sv);
}
else if (gimme != G_VOID)
PUSHs(unsliced_keysv);

RETURN;
}
Expand Down

0 comments on commit ca3f996

Please sign in to comment.