PL_op->op_type == OP_REWINDDIR ||
PL_op->op_type == OP_CLOSEDIR ?
"dirhandle" : "filehandle";
+ /* diag_listed_as: Bad symbol for filehandle */
Perl_croak(aTHX_ "Bad symbol for %s", fh);
}
if (!GvIOp(gv)) {
-#ifdef GV_UNIQUE_CHECK
- if (GvUNIQUE(gv)) {
- Perl_croak(aTHX_ "Bad symbol for filehandle (GV is unique)");
- }
-#endif
GvIOp(gv) = newIO();
}
return gv;
(sv_type == SVt_PVAV && !GvIMPORTED_AV(*gvp)) ||
(sv_type == SVt_PVHV && !GvIMPORTED_HV(*gvp)) )
{
+ /* diag_listed_as: Variable "%s" is not imported%s */
Perl_warn(aTHX_ "Variable \"%c%s\" is not imported",
sv_type == SVt_PVAV ? '@' :
sv_type == SVt_PVHV ? '%' : '$',
if (strEQ(name2, "IG")) {
HV *hv;
I32 i;
- if (!PL_psig_ptr) {
- Newxz(PL_psig_ptr, SIG_SIZE, SV*);
- Newxz(PL_psig_name, SIG_SIZE, SV*);
+ if (!PL_psig_name) {
+ Newxz(PL_psig_name, 2 * SIG_SIZE, SV*);
Newxz(PL_psig_pend, SIG_SIZE, int);
+ PL_psig_ptr = PL_psig_name + SIG_SIZE;
+ } else {
+ /* I think that the only way to get here is to re-use an
+ embedded perl interpreter, where the previous
+ use didn't clean up fully because
+ PL_perl_destruct_level was 0. I'm not sure that we
+ "support" that, in that I suspect in that scenario
+ there are sufficient other garbage values left in the
+ interpreter structure that something else will crash
+ before we get here. I suspect that this is one of
+ those "doctor, it hurts when I do this" bugs. */
+ Zero(PL_psig_name, 2 * SIG_SIZE, SV*);
+ Zero(PL_psig_pend, SIG_SIZE, int);
}
GvMULTI_on(gv);
hv = GvHVn(gv);
SV * const * const init = hv_fetch(hv, PL_sig_name[i], strlen(PL_sig_name[i]), 1);
if (init)
sv_setsv(*init, &PL_sv_undef);
- PL_psig_ptr[i] = 0;
- PL_psig_name[i] = 0;
- PL_psig_pend[i] = 0;
}
}
break;
ro_magicalize:
SvREADONLY_on(GvSVn(gv));
/* FALL THROUGH */
+ case '0':
case '1':
case '2':
case '3':
}
/* Updates and caches the CV's */
+/* Returns:
+ * 1 on success and there is some overload
+ * 0 if there is no overload
+ * -1 if some error occurred and it couldn't croak
+ */
-bool
-Perl_Gv_AMupdate(pTHX_ HV *stash)
+int
+Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
{
dVAR;
MAGIC* const mg = mg_find((const SV *)stash, PERL_MAGIC_overload_table);
const AMT * const amtp = (AMT*)mg->mg_ptr;
if (amtp->was_ok_am == PL_amagic_generation
&& amtp->was_ok_sub == newgen) {
- return (bool)AMT_OVERLOADED(amtp);
+ return AMT_OVERLOADED(amtp) ? 1 : 0;
}
sv_unmagic(MUTABLE_SV(stash), PERL_MAGIC_overload_table);
}
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 -1;
+ }
+ 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);
}
AMT_AMAGIC_off(&amt);
sv_magic(MUTABLE_SV(stash), 0, PERL_MAGIC_overload_table,
(char*)&amt, sizeof(AMTS));
- return FALSE;
+ return 0;
}
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) == -1) {
+ /* 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);
* masked by overloading.pm */
STRLEN len;
const int offset = method / 8;
- const int bit = method % 7;
+ const int bit = method % 8;
char *pv = SvPV(lex_mask, len);
/* Bit set, so this overloading operator is disabled */
- if ( (STRLEN)offset <= len && pv[offset] & ( 1 << bit ) )
+ if ( (STRLEN)offset < len && pv[offset] & ( 1 << bit ) )
return NULL;
}
}
break;
case int_amg:
case iter_amg: /* XXXX Eventually should do to_gv. */
+ case ftest_amg: /* XXXX Eventually should do to_gv. */
/* FAIL safe */
return NULL; /* Delegate operation to standard mechanisms. */
break;