This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Propagate (non-)lvalue context through nested calls
authorFather Chrysostomos <sprout@cpan.org>
Sun, 10 Jul 2011 02:18:45 +0000 (19:18 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 10 Jul 2011 02:19:51 +0000 (19:19 -0700)
commit777d9014444bb88a98ccd6c09ebb520cdc4c0d8b
treeadd55b04929f0bc1462315c6aa167b4bfa2c641e
parentfe57f3b7598666107c5e6e9c9ffd844da47ea527
Propagate (non-)lvalue context through nested calls

Before this commit, this code would fail:

$foo = "foo";
sub foo :lvalue{ return index "foo","o" }
sub bar :lvalue { foo }
$x = bar;

(It would fail for ‘return $]’ as well.  Whether it’s a PADTMP or a
read-only scalar makes no difference.)

foo would think it was being called in true lvalue context, because
the entersub op that called it (in bar) was marked that way, bar being
an lvalue sub as well.

The PUSHSUB macro in cop.h needed to be modified to account for
dynamic, or indetermine, context (i.e., indeterminable at compile
time).  This happens when an entersub op is an argument to return or
the last statement in a subroutine.  In those cases it has to propa-
gate the context from the caller.

So what we now do is this: Both lvalue and in-args flags are turned on
for an entersub op when op_lvalue is called with OP_LEAVESUBLV as the
type.  Then PUSHSUB copies into the context stack only those flags
that are set both on the current entersub op and in the context stack
for the previous sub call.
cop.h
embed.fnc
embed.h
op.c
op.h
pod/perldelta.pod
pp_ctl.c
proto.h
t/op/sub_lval.t