summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2010-09-26 11:09:28 -0700
committerFather Chrysostomos <sprout@cpan.org>2010-09-26 11:09:28 -0700
commit13be902cef8b01c085a6b8b1b59fa2754a10cdfb (patch)
tree36349eb3f2bffa12f01cf0fa38a37036a8b80448 /pp_hot.c
parent25e68b8bdd34f742e9a4780090bafa60c943ec14 (diff)
downloadperl-13be902cef8b01c085a6b8b1b59fa2754a10cdfb.tar.gz
[perl #77362] Assigning glob to lvalue causes stringification
This test from t/op/gv.t was added by change 22315/4ce457a6: { # test the assignment of a GLOB to an LVALUE my $e = ''; local $SIG{__DIE__} = sub { $e = $_[0] }; my $v; sub f { $_[0] = 0; $_[0] = "a"; $_[0] = *DATA } f($v); is ($v, '*main::DATA'); my $x = <$v>; is ($x, "perl\n"); } That change was the one that made glob-to-lvalue assignment work to begin with. But this test passes in perl version *prior* to that change. This patch fixes the test and adds tests to make sure what is assigned is actually a glob, and not just a string. It also happens to fix the stringification bug. In doing so, it essen- tially ‘enables’ globs-as-PVLVs. It turns out that many different parts of the perl source don’t fully take this into account, so this patch also fixes the following to work with them (I tried to make these into separate patches, but they are so intertwined it just got too complicated): • GvIO(gv) to make readline and other I/O ops work. • Autovivification of glob slots. • tie *$pvlv • *$pvlv = undef, *$pvlv = $number, *$pvlv = $ref • Duplicating a filehandle accessed through a PVLV glob when the stringified form of the glob cannot be used to access the file handle (!) • Using a PVLV glob as a subroutine reference • Coderef assignment when the glob is no longer in the symbol table • open with a PVLV glob for the filehandle • -t and -T • Unopened file handle warnings
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 4f043fb5f7..4db0e23914 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -123,7 +123,7 @@ PP(pp_sassign)
if (PL_op->op_private & OPpASSIGN_CV_TO_GV) {
SV * const cv = SvRV(left);
const U32 cv_type = SvTYPE(cv);
- const U32 gv_type = SvTYPE(right);
+ const bool is_gv = isGV_with_GP(right);
const bool got_coderef = cv_type == SVt_PVCV || cv_type == SVt_PVFM;
if (!got_coderef) {
@@ -133,7 +133,7 @@ PP(pp_sassign)
/* Can do the optimisation if right (LVALUE) is not a typeglob,
left (RVALUE) is a reference to something, and we're in void
context. */
- if (!got_coderef && gv_type != SVt_PVGV && GIMME_V == G_VOID) {
+ if (!got_coderef && !is_gv && GIMME_V == G_VOID) {
/* Is the target symbol table currently empty? */
GV * const gv = gv_fetchsv(right, GV_NOINIT, SVt_PVGV);
if (SvTYPE(gv) != SVt_PVGV && !SvOK(gv)) {
@@ -151,7 +151,7 @@ PP(pp_sassign)
}
/* Need to fix things up. */
- if (gv_type != SVt_PVGV) {
+ if (!is_gv) {
/* Need to fix GV. */
right = MUTABLE_SV(gv_fetchsv(right, GV_ADD, SVt_PVGV));
}
@@ -201,7 +201,7 @@ PP(pp_sassign)
/* Allow glob assignments like *$x = ..., which, when the glob has a
SVf_FAKE flag, cannot be distinguished from $x = ... without looking
at the op tree. */
- if( SvTYPE(right) == SVt_PVGV && cBINOP->op_last->op_type == OP_RV2GV
+ if( isGV_with_GP(right) && cBINOP->op_last->op_type == OP_RV2GV
&& (wasfake = SvFLAGS(right) & SVf_FAKE) )
SvFLAGS(right) &= ~SVf_FAKE;
SvSetMagicSV(right, left);
@@ -2749,6 +2749,7 @@ PP(pp_entersub)
case SVt_PVGV:
if (!isGV_with_GP(sv))
DIE(aTHX_ "Not a CODE reference");
+ we_have_a_glob:
if (!(cv = GvCVu((const GV *)sv))) {
HV *stash;
cv = sv_2cv(sv, &stash, &gv, 0);
@@ -2759,6 +2760,9 @@ PP(pp_entersub)
goto try_autoload;
}
break;
+ case SVt_PVLV:
+ if(isGV_with_GP(sv)) goto we_have_a_glob;
+ /*FALLTHROUGH*/
default:
if (sv == &PL_sv_yes) { /* unfound import, ignore */
if (hasargs)