Skip to content

Commit

Permalink
make RC-stack-aware: unwrap pp_emptyavhv()
Browse files Browse the repository at this point in the history
Remove the temporary wrapper from pp_emptyavhv()

Also fix some tests in array.t, which were expecting a temp empty array
ref to be prematurely freed. With PERL_RC_STACK, it's no longer
prematurely freed.
  • Loading branch information
iabyn committed Nov 16, 2023
1 parent 25d6d0c commit 23ec0ba
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
16 changes: 7 additions & 9 deletions pp.c
Expand Up @@ -5969,9 +5969,8 @@ PP(pp_anonlist)
/* When an anonlist or anonhash will (1) be empty and (2) return an RV
* pointing to the new AV/HV, the peephole optimizer can swap in this
* simpler function and op_null the originally associated PUSHMARK. */
PP_wrapped(pp_emptyavhv, 0,0)
PP(pp_emptyavhv)
{
dSP;
OP * const op = PL_op;
SV * rv;
SV * const sv = MUTABLE_SV( newSV_type(
Expand All @@ -5996,19 +5995,18 @@ PP_wrapped(pp_emptyavhv, 0,0)
save_clearsv(padentry);
}
if (GIMME_V == G_VOID) {
RETURN; /* skip extending and pushing */
return NORMAL; /* skip extending and pushing */
}
rpp_xpush_1(rv);
} else {
/* Inlined newRV_noinc */
SV * refsv = newSV_type_mortal(SVt_IV);
SV * refsv = newSV_type(SVt_IV);
SvRV_set(refsv, sv);
SvROK_on(refsv);

rv = refsv;
rpp_extend(1);
rpp_push_1_norc(refsv);
}

XPUSHs(rv);
RETURN;
return NORMAL; /* skip extending and pushing */
}


Expand Down
20 changes: 14 additions & 6 deletions t/op/array.t
Expand Up @@ -265,21 +265,29 @@ is ($got, '');
}

sub test_arylen {
my $ref = shift;
my ($ref, , $fixed, $desc) = @_;
local $^W = 1;
is ($$ref, undef, "\$# on freed array is undef");
# on RC builds, the temp [] array isn't prematurely freed:
# the \$# magic var keeps it alive.
my $is_rc = $fixed && (Internals::stack_refcounted() & 1);
is ($$ref, ($is_rc ? - 1 : undef), "$desc: \$# on freed array is undef");
my @warn;
local $SIG{__WARN__} = sub {push @warn, "@_"};
$$ref = 1000;
is (scalar @warn, 1);
like ($warn[0], qr/^Attempt to set length of freed array/);
is (scalar @warn, ($is_rc ? 0 : 1), "$desc: number of warnings");
if ($is_rc) {
pass("$desc: pass");
}
else {
like ($warn[0], qr/^Attempt to set length of freed array/, "$desc: msg");
}
}

{
my $a = \$#{[]};
# Need a new statement to make it go out of scope
test_arylen ($a);
test_arylen (do {my @a; \$#a});
test_arylen ($a, 1, "\$a");
test_arylen (do {my @a; \$#a}, 0, "do {}");
}

{
Expand Down

0 comments on commit 23ec0ba

Please sign in to comment.