Here's a patch against perl5.001m for
NETaa14561 N 1 k $@ vs DESTROY
This prevents mortal OBJECTs (with user-defined destructors) created in the
last statement in an eval block from clobbering the eval's $@.
This will also trap a fatal error inside DESTROY's (but only display the
error message as a mandatory warning).
[.I have attempted a feeble optimization (using hv_fetch() instead of a
gv_fetchpv()), but I think the gv_fetchmethod() and perl_call_sv()
would be far more expensive...]
- Sarathy.
gsar@engin.umich.edu
------------------------------------8<------------------------------
*** sv.c.dist Mon Sep 4 23:02:45 1995
--- sv.c Mon Sep 4 23:02:58 1995
***************
*** 2112,2117 ****
--- 2112,2126 ----
SAVEFREESV(SvSTASH(sv));
if (destructor && GvCV(destructor)) {
SV ref;
+ SV *errsv = Nullsv;
+ SV *saverr = Nullsv;
+ GV **gvp = (GV**)hv_fetch(defstash, "@", 1, TRUE);
+ if (gvp && *gvp && (SvTYPE(*gvp) == SVt_PVGV)) {
+ SvMULTI_on(*gvp);
+ errsv = GvSV(*gvp);
+ }
+ if (SvTRUE(errsv)) /* save previous $@ */
+ saverr = newSVsv(errsv);
Zero(&ref, 1, SV);
sv_upgrade(&ref, SVt_RV);
***************
*** 2124,2129 ****
--- 2133,2144 ----
PUSHs(&ref);
PUTBACK;
perl_call_sv((SV*)destructor, G_DISCARD|G_EVAL);
+ if (SvTRUE(errsv))
+ warn("Trapped error in DESTROY: %s", SvPVx(errsv, na));
+ if (saverr != Nullsv) {
+ sv_setsv(errsv, saverr);
+ sv_free(saverr);
+ }
del_XRV(SvANY(&ref));
}
LEAVE;
NETaa14561 N 1 k $@ vs DESTROY
This prevents mortal OBJECTs (with user-defined destructors) created in the
last statement in an eval block from clobbering the eval's $@.
This will also trap a fatal error inside DESTROY's (but only display the
error message as a mandatory warning).
[.I have attempted a feeble optimization (using hv_fetch() instead of a
gv_fetchpv()), but I think the gv_fetchmethod() and perl_call_sv()
would be far more expensive...]
- Sarathy.
gsar@engin.umich.edu
------------------------------------8<------------------------------
*** sv.c.dist Mon Sep 4 23:02:45 1995
--- sv.c Mon Sep 4 23:02:58 1995
***************
*** 2112,2117 ****
--- 2112,2126 ----
SAVEFREESV(SvSTASH(sv));
if (destructor && GvCV(destructor)) {
SV ref;
+ SV *errsv = Nullsv;
+ SV *saverr = Nullsv;
+ GV **gvp = (GV**)hv_fetch(defstash, "@", 1, TRUE);
+ if (gvp && *gvp && (SvTYPE(*gvp) == SVt_PVGV)) {
+ SvMULTI_on(*gvp);
+ errsv = GvSV(*gvp);
+ }
+ if (SvTRUE(errsv)) /* save previous $@ */
+ saverr = newSVsv(errsv);
Zero(&ref, 1, SV);
sv_upgrade(&ref, SVt_RV);
***************
*** 2124,2129 ****
--- 2133,2144 ----
PUSHs(&ref);
PUTBACK;
perl_call_sv((SV*)destructor, G_DISCARD|G_EVAL);
+ if (SvTRUE(errsv))
+ warn("Trapped error in DESTROY: %s", SvPVx(errsv, na));
+ if (saverr != Nullsv) {
+ sv_setsv(errsv, saverr);
+ sv_free(saverr);
+ }
del_XRV(SvANY(&ref));
}
LEAVE;