diff options
author | Nicholas Clark <nick@ccl4.org> | 2004-07-05 10:24:17 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2004-07-05 10:24:17 +0000 |
commit | 6683b158708b1cc33880334eb3d2b4e2debe9fab (patch) | |
tree | a604d3838b31608475aac385d0364a75b5c1dfbf /mg.c | |
parent | 9d7d97294754b044f4b4bee93dbdfb1d82ffe0d7 (diff) | |
download | perl-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.c | 34 |
1 files changed, 18 insertions, 16 deletions
@@ -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; } |