diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-08-14 19:16:14 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-08-15 06:20:19 -0700 |
commit | f79aa60b66082c8bff80f325979742bfb6c73709 (patch) | |
tree | 9abac236ef8e21df8d6080190f3e12e2aae9eadd /op.c | |
parent | 186abd568524c217f6dbd29891eef21c3cd2a3b0 (diff) | |
download | perl-f79aa60b66082c8bff80f325979742bfb6c73709.tar.gz |
Make lock(&foo) syntax nominally lock the subroutine
In 5.10, lock(&foo) was an error for non-lvalue subs. For lvalue
subs, it passed &foo to the lockhook and return \&foo.
In 5.12, lock(&foo) was still an error for non-lvalue subs. For
lvalue subs, it would pass &foo to the lockhook and then either
trip an assertion (-DDEBUGGING) or return &foo, resulting in inter-
esting bugs.
Commit f4df43b5e changed lock(&lvalue_sub) to call the sub and lock
its return value.
As Reini Urban pointed out in
<CAHiT=DE5cVZbuCR3kb=Q5oCa18vo3jr5jZKmURHYha2PwF4pEQ@mail.gmail.com>,
locking a subroutine does have its uses.
Since lock(&foo) has never really worked anyway, we can still
change this.
So, for lvalue subs, this reverts back to the 5.10 behaviour. For
non-lvalue subs, it now behaves the same way, the lvalue flag making
no difference. Note that it still causes an error at run-time, if
threads::shared is loaded, as its lockhook is conservative in what
it accepts.
But this change allows for future extensibility, unlike f4df43b5e.
A note about the implementation: There are two pieces of code (at
least) in op.c that convert an entersub op into an rv2cv, one in
S_doref and the other in Perl_op_lvalue_flags. Originally (before
f4df43b5e) it was S_doref that took care of that for OP_LOCK. But
Perl_op_lvalue_flags is called first, so it would assume it was an
assignment to a sub call and croak if there was no lvalue sub in the
symbol table. This commit adds back the special case for OP_LOCK, but
in Perl_op_lvalue_flags, not S_doref.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 3 |
1 files changed, 2 insertions, 1 deletions
@@ -1705,7 +1705,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags) break; goto nomod; case OP_ENTERSUB: - if ((type == OP_UNDEF || type == OP_REFGEN) && + if ((type == OP_UNDEF || type == OP_REFGEN || type == OP_LOCK) && !(o->op_flags & OPf_STACKED)) { o->op_type = OP_RV2CV; /* entersub => rv2cv */ /* Both ENTERSUB and RV2CV use this bit, but for different pur- @@ -10415,6 +10415,7 @@ Perl_core_prototype(pTHX_ SV *sv, const char *name, const int code, str[n++] = '$'; str[n++] = '@'; str[n++] = '%'; + if (i == OP_LOCK) str[n++] = '&'; str[n++] = '*'; str[n++] = ']'; } |