summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1997-12-31 14:30:46 -0500
committerGurusamy Sarathy <gsar@cpan.org>1998-02-09 02:30:43 +0000
commit4e8e7886db513516f1ffb27b8c762a5fd6831099 (patch)
treec5c349fcb62284c5b7fdaa37bc6f862d880d90b0 /sv.c
parentd665c133375efdf305833da1aceeebefc5d313d9 (diff)
downloadperl-4e8e7886db513516f1ffb27b8c762a5fd6831099.tar.gz
[win32] fix for bugs in handling DESTROY (adjusted test numbers)
Message-Id: <199801010030.TAA14274@aatma.engin.umich.edu> Subject: Re: [PERL] RFD: iterative DESTROYing of objects p4raw-id: //depot/win32/perl@490
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c54
1 files changed, 27 insertions, 27 deletions
diff --git a/sv.c b/sv.c
index 9de271bc40..f460e45b3f 100644
--- a/sv.c
+++ b/sv.c
@@ -2646,37 +2646,37 @@ sv_clear(register SV *sv)
if (defstash) { /* Still have a symbol table? */
djSP;
GV* destructor;
+ HV* stash;
+ SV ref;
- ENTER;
- SAVEFREESV(SvSTASH(sv));
-
- destructor = gv_fetchmethod(SvSTASH(sv), "DESTROY");
- if (destructor) {
- SV ref;
-
- Zero(&ref, 1, SV);
- sv_upgrade(&ref, SVt_RV);
- SvRV(&ref) = SvREFCNT_inc(sv);
- SvROK_on(&ref);
- SvREFCNT(&ref) = 1; /* Fake, but otherwise
- creating+destructing a ref
- leads to disaster. */
-
- EXTEND(SP, 2);
- PUSHMARK(SP);
- PUSHs(&ref);
- PUTBACK;
- perl_call_sv((SV*)GvCV(destructor),
- G_DISCARD|G_EVAL|G_KEEPERR);
- del_XRV(SvANY(&ref));
- SvREFCNT(sv)--;
- }
+ Zero(&ref, 1, SV);
+ sv_upgrade(&ref, SVt_RV);
+ SvROK_on(&ref);
+ SvREADONLY_on(&ref); /* DESTROY() could be naughty */
+ SvREFCNT(&ref) = 1;
- LEAVE;
+ do {
+ stash = SvSTASH(sv);
+ destructor = gv_fetchmethod(SvSTASH(sv), "DESTROY");
+ if (destructor) {
+ ENTER;
+ SvRV(&ref) = SvREFCNT_inc(sv);
+ EXTEND(SP, 2);
+ PUSHMARK(SP);
+ PUSHs(&ref);
+ PUTBACK;
+ perl_call_sv((SV*)GvCV(destructor),
+ G_DISCARD|G_EVAL|G_KEEPERR);
+ SvREFCNT(sv)--;
+ LEAVE;
+ }
+ } while (SvOBJECT(sv) && SvSTASH(sv) != stash);
+
+ del_XRV(SvANY(&ref));
}
- else
- SvREFCNT_dec(SvSTASH(sv));
+
if (SvOBJECT(sv)) {
+ SvREFCNT_dec(SvSTASH(sv)); /* possibly of changed persuasion */
SvOBJECT_off(sv); /* Curse the object. */
if (SvTYPE(sv) != SVt_PVIO)
--sv_objcount; /* XXX Might want something more general */