summaryrefslogtreecommitdiff
path: root/scope.c
diff options
context:
space:
mode:
authorLubomir Rintel (GoodData) <lubo.rintel@gooddata.com>2010-04-22 18:19:23 +0200
committerRafael Garcia-Suarez <rgs@consttype.org>2010-04-26 11:52:48 +0200
commitb9e00b79e4947c49d5520633f9efd2a8e39ec14f (patch)
treef870176dcfc5732189e4cca4c216ca4cb4600254 /scope.c
parent01146bad274273e459645fb4cce5aeac95999d64 (diff)
downloadperl-b9e00b79e4947c49d5520633f9efd2a8e39ec14f.tar.gz
Globs that are in symbol table can be un-globbed
If a symbol table entry is undefined when a glob is assigned into it, it gets a FAKE flag which makes it possible to be downgraded when non-glob is subsequently assigned into it. It doesn't really matter, until we decide to localize it -- it wouldn't be possible to restore its GP upon context return if it changed type, therefore we must not do that. This patch turns off FAKE flag when localizing a GV and restores it when the context is left. A test case is included.
Diffstat (limited to 'scope.c')
-rw-r--r--scope.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/scope.c b/scope.c
index 6ee1254b60..64939338ce 100644
--- a/scope.c
+++ b/scope.c
@@ -281,7 +281,15 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty)
PERL_ARGS_ASSERT_SAVE_GP;
- save_pushptrptr(SvREFCNT_inc(gv), GvGP(gv), SAVEt_GP);
+ SSCHECK(4);
+ SSPUSHINT(SvFAKE(gv));
+ SSPUSHPTR(GvGP(gv));
+ SSPUSHPTR(SvREFCNT_inc(gv));
+ SSPUSHINT(SAVEt_GP);
+
+ /* Don't let the localized GV coerce into non-glob, otherwise we would
+ * not be able to restore GP upon leave from context if that happened */
+ SvFAKE_off(gv);
if (empty) {
GP *gp = Perl_newGP(aTHX_ gv);
@@ -812,10 +820,11 @@ Perl_leave_scope(pTHX_ I32 base)
*(AV**)ptr = MUTABLE_AV(SSPOPPTR);
break;
case SAVEt_GP: /* scalar reference */
- ptr = SSPOPPTR;
gv = MUTABLE_GV(SSPOPPTR);
gp_free(gv);
- GvGP(gv) = (GP*)ptr;
+ GvGP(gv) = (GP*)SSPOPPTR;
+ if (SSPOPINT)
+ SvFAKE_on(gv);
/* putting a method back into circulation ("local")*/
if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvNAME_get(hv))
mro_method_changed_in(hv);