summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2004-07-05 10:24:17 +0000
committerNicholas Clark <nick@ccl4.org>2004-07-05 10:24:17 +0000
commit6683b158708b1cc33880334eb3d2b4e2debe9fab (patch)
treea604d3838b31608475aac385d0364a75b5c1dfbf /mg.c
parent9d7d97294754b044f4b4bee93dbdfb1d82ffe0d7 (diff)
downloadperl-6683b158708b1cc33880334eb3d2b4e2debe9fab.tar.gz
t/op/tie.t test 23 is failing when run with utf8 everywhere.
Problem appears to be due to theft of temporaries p4raw-id: //depot/perl@23040
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c34
1 files changed, 18 insertions, 16 deletions
diff --git a/mg.c b/mg.c
index 48213dc789..4ab7f4f96f 100644
--- a/mg.c
+++ b/mg.c
@@ -129,21 +129,19 @@ Perl_mg_get(pTHX_ SV *sv)
int new = 0;
MAGIC *newmg, *head, *cur, *mg;
I32 mgs_ix = SSNEW(sizeof(MGS));
+ int was_temp = SvTEMP(sv);
/* guard against sv having being freed midway by holding a private
- reference. It's not possible to make this sv mortal without failing
- several tests -
- looks like it's important that it can get DESTROYed before the next
- FREETMPS
- Also it's not possible to wrap this function in a SAVETMPS/FREETMPS
- pair. We need drop our reference if croak() is called, but we also
- can't simply make it mortal and wait for the next FREETMPS, because
- other tests rely on the sv being freed earlier. Hence this hack.
- We create an extra reference on the caller's sv, owned by the rv,
- which is mortal. If croak is called the RV cleans up for us.
- If we reach the end of the function we change it to point at
- PL_sv_undef, and clean up manually. */
- SV *temp_rv = sv_2mortal(newRV_inc(sv));
-
+ reference. */
+
+ /* sv_2mortal has this side effect of turning on the TEMP flag, which can
+ cause the SV's buffer to get stolen (and maybe other stuff).
+ So restore it.
+ */
+ sv_2mortal(SvREFCNT_inc(sv));
+ if (!was_temp) {
+ SvTEMP_off(sv);
+ }
+
save_magic(mgs_ix, sv);
/* We must call svt_get(sv, mg) for each valid entry in the linked
@@ -188,8 +186,12 @@ Perl_mg_get(pTHX_ SV *sv)
}
restore_magic(aTHX_ INT2PTR(void *, (IV)mgs_ix));
- SvRV(temp_rv) = &PL_sv_undef;
- SvREFCNT_dec(sv);
+
+ if (SvREFCNT(sv) == 1) {
+ /* We hold the last reference to this SV, which implies that the
+ SV was deleted as a side effect of the routines we called. */
+ SvOK_off(sv);
+ }
return 0;
}