diff options
author | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2009-07-08 16:56:50 +0200 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2009-07-08 23:32:22 +0200 |
commit | 242f8760e6ec383f070c854a602d038abeaf355a (patch) | |
tree | 3b84b59911c540c9813ceb3ae12a9f573ee273cf /gv.c | |
parent | e5b34a76788f710069f8da5111b19844263dbf3f (diff) | |
download | perl-242f8760e6ec383f070c854a602d038abeaf355a.tar.gz |
Add a parameter "destructing" to Gv_AMupdate()
This boolean parameter indicates if the function has been called
to update the overload magic table while looking up the DESTROY
method. In this case, it's probably best to avoid croaking if
those tables could not be updated (for example due to a method
that could not be loaded.)
Diffstat (limited to 'gv.c')
-rw-r--r-- | gv.c | 33 |
1 files changed, 25 insertions, 8 deletions
@@ -1666,7 +1666,7 @@ Perl_magic_freeovrld(pTHX_ SV *sv, MAGIC *mg) /* Updates and caches the CV's */ bool -Perl_Gv_AMupdate(pTHX_ HV *stash) +Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing) { dVAR; MAGIC* const mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table); @@ -1757,12 +1757,17 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) FALSE))) { /* Can be an import stub (created by "can"). */ - const char * const name = (gvsv && SvPOK(gvsv)) ? SvPVX_const(gvsv) : "???"; - Perl_croak(aTHX_ "%s method \"%.256s\" overloading \"%s\" "\ - "in package \"%.256s\"", - (GvCVGEN(gv) ? "Stub found while resolving" - : "Can't resolve"), - name, cp, hvname); + if (destructing) { + return FALSE; + } + else { + const char * const name = (gvsv && SvPOK(gvsv)) ? SvPVX_const(gvsv) : "???"; + Perl_croak(aTHX_ "%s method \"%.256s\" overloading \"%s\" "\ + "in package \"%.256s\"", + (GvCVGEN(gv) ? "Stub found while resolving" + : "Can't resolve"), + name, cp, hvname); + } } cv = GvCV(gv = ngv); } @@ -1814,7 +1819,19 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id) mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table); if (!mg) { do_update: - Gv_AMupdate(stash); + /* If we're looking up a destructor to invoke, we must avoid + * that Gv_AMupdate croaks, because we might be dying already */ + if (!Gv_AMupdate(stash, id == DESTROY_amg)) { + /* and if it didn't found a destructor, we fall back + * to a simpler method that will only look for the + * destructor instead of the whole magic */ + if (id == DESTROY_amg) { + GV * const gv = gv_fetchmethod(stash, "DESTROY"); + if (gv) + return GvCV(gv); + } + return NULL; + } mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table); } assert(mg); |