summaryrefslogtreecommitdiff
path: root/op.h
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-12-17 23:01:07 -0800
committerFather Chrysostomos <sprout@cpan.org>2011-12-17 23:19:04 -0800
commit8dc99089b7dd2506e907c4344ed28a3206866f37 (patch)
tree2b28cabfeba32d6a8fc290e622a14e7e0a99cc9b /op.h
parent8cd0c082aacc4c22b60ef4afdb96e244a082d4c1 (diff)
downloadperl-8dc99089b7dd2506e907c4344ed28a3206866f37.tar.gz
Stop tell($glob_copy) from clearing PL_last_in_gv
This bug is a side effect of rv2gv’s starting to return an incoercible mortal copy of a coercible glob in 5.14: $ perl5.12.4 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell' 0 $ perl5.14.0 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell' -1 In the first case, tell without arguments is returning the position of the filehandle. In the second case, tell with an explicit argument that happens to be a coercible glob (tell has an implicit rv2gv, so tell $fh is actu- ally tell *$fh) sets PL_last_in_gv to a mortal copy thereof, which is freed at the end of the statement, setting PL_last_in_gv to null. So there is no ‘last used’ handle by the time we get to the tell without arguments. This commit adds a new rv2gv flag that tells it not to copy the glob. By doing it unconditionally on the kidop, this allows tell(*$fh) to work the same way. Let’s hope nobody does tell(*{*$fh}), which will unset PL_last_in_gv because the inner * returns a mortal copy. This whole area is really icky. PL_last_in_gv should be refcounted, but that would cause handles to leak out of scope, breaking programs that rely on the auto-closing ‘feature’.
Diffstat (limited to 'op.h')
-rw-r--r--op.h6
1 files changed, 4 insertions, 2 deletions
diff --git a/op.h b/op.h
index 0758f9c910..ffa9a3f163 100644
--- a/op.h
+++ b/op.h
@@ -225,7 +225,7 @@ Deprecated. Use C<GIMME_V> instead.
#define OPpEARLY_CV 32 /* foo() called before sub foo was parsed */
/* OP_?ELEM only */
#define OPpLVAL_DEFER 16 /* Defer creation of array/hash elem */
- /* OP_RV2?V, OP_GVSV, OP_ENTERITER only */
+ /* OP_RV2[SAH]V, OP_GVSV, OP_ENTERITER only */
#define OPpOUR_INTRO 16 /* Variable was in an our() */
/* OP_RV2[AGH]V, OP_PAD[AH]V, OP_[AH]ELEM, OP_[AH]SLICE OP_AV2ARYLEN,
OP_R?KEYS, OP_SUBSTR, OP_POS, OP_VEC */
@@ -242,6 +242,7 @@ Deprecated. Use C<GIMME_V> instead.
#define OPpDONT_INIT_GV 4 /* Call gv_fetchpv with GV_NOINIT */
/* (Therefore will return whatever is currently in the symbol table, not
guaranteed to be a PVGV) */
+#define OPpALLOW_FAKE 16 /* OK to return fake glob */
/* Private for OP_ENTERITER and OP_ITER */
#define OPpITER_REVERSED 4 /* for (reverse ...) */
@@ -308,7 +309,8 @@ Deprecated. Use C<GIMME_V> instead.
#define OPpOFFBYONE 128 /* Treat caller(1) as caller(2) */
/* Private for OP_COREARGS */
-/* These must not conflict with OPpDONT_INIT_GV. See pp.c:S_rv2gv. */
+/* These must not conflict with OPpDONT_INIT_GV or OPpALLOW_FAKE.
+ See pp.c:S_rv2gv. */
#define OPpCOREARGS_DEREF1 1 /* Arg 1 is a handle constructor */
#define OPpCOREARGS_DEREF2 2 /* Arg 2 is a handle constructor */
#define OPpCOREARGS_SCALARMOD 64 /* \$ rather than \[$@%*] */