summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorArtur Bergman <sky@nanisky.com>2003-04-19 00:40:42 +0000
committerArtur Bergman <sky@nanisky.com>2003-04-19 00:40:42 +0000
commitb34402ddaa7fb5ef7e3c209ae505ec005d5a34dd (patch)
treee746ae67d348b8b3bcc770c0329e6f5cca04f095 /sv.c
parentbf29be10504ebf4caff9a3799bc572cdca38918c (diff)
downloadperl-b34402ddaa7fb5ef7e3c209ae505ec005d5a34dd.tar.gz
Don't use the stack to allocate a SV that we hand out to another
function, only badness can ensure. Message-Id: <20030418180131.GD10086@fdgroup.com> Thanks go to Dave Mitchell for help in tracking down the bug! p4raw-id: //depot/perl@19265
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/sv.c b/sv.c
index 5a512697cc..1de42fb1ce 100644
--- a/sv.c
+++ b/sv.c
@@ -5309,34 +5309,37 @@ Perl_sv_clear(pTHX_ register SV *sv)
if (PL_defstash) { /* Still have a symbol table? */
dSP;
CV* destructor;
- SV tmpref;
- Zero(&tmpref, 1, SV);
- sv_upgrade(&tmpref, SVt_RV);
- SvROK_on(&tmpref);
- SvREADONLY_on(&tmpref); /* DESTROY() could be naughty */
- SvREFCNT(&tmpref) = 1;
+
do {
stash = SvSTASH(sv);
destructor = StashHANDLER(stash,DESTROY);
if (destructor) {
+ SV* tmpref = newRV(sv);
+ SvREADONLY_on(tmpref); /* DESTROY() could be naughty */
ENTER;
PUSHSTACKi(PERLSI_DESTROY);
- SvRV(&tmpref) = SvREFCNT_inc(sv);
EXTEND(SP, 2);
PUSHMARK(SP);
- PUSHs(&tmpref);
+ PUSHs(tmpref);
PUTBACK;
call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID);
- SvREFCNT(sv)--;
+
+
POPSTACK;
SPAGAIN;
LEAVE;
+ if(SvREFCNT(tmpref) < 2) {
+ /* tmpref is not kept alive! */
+ SvREFCNT(sv)--;
+ SvRV(tmpref) = 0;
+ SvROK_off(tmpref);
+ }
+ SvREFCNT_dec(tmpref);
}
} while (SvOBJECT(sv) && SvSTASH(sv) != stash);
- del_XRV(SvANY(&tmpref));
if (SvREFCNT(sv)) {
if (PL_in_clean_objs)