const bool doproto = old_type > SVt_NULL;
const char * const proto = (doproto && SvPOK(gv)) ? SvPVX_const(gv) : NULL;
SV *const has_constant = doproto && SvROK(gv) ? SvRV(gv) : NULL;
+ const U32 exported_constant = has_constant ? SvPCS_IMPORTED(gv) : 0;
assert (!(proto && has_constant));
case SVt_PVIO:
Perl_croak(aTHX_ "Cannot convert a reference to %s to typeglob",
sv_reftype(has_constant, 0));
+ default: NOOP;
}
SvRV_set(gv, NULL);
SvROK_off(gv);
} else
Safefree(SvPVX_mutable(gv));
}
- SvSCREAM_on(gv);
+ SvIOK_off(gv);
+ isGV_with_GP_on(gv);
GvGP(gv) = Perl_newGP(aTHX_ gv);
GvSTASH(gv) = stash;
if (multi || doproto) /* doproto means it _was_ mentioned */
GvMULTI_on(gv);
if (doproto) { /* Replicate part of newSUB here. */
- SvIOK_off(gv);
ENTER;
if (has_constant) {
/* newCONSTSUB takes ownership of the reference from us. */
GvCV(gv) = newCONSTSUB(stash, name, has_constant);
+ /* If this reference was a copy of another, then the subroutine
+ must have been "imported", by a Perl space assignment to a GV
+ from a reference to CV. */
+ if (exported_constant)
+ GvIMPORTED_CV_on(gv);
} else {
/* XXX unsafe for threads if eval_owner isn't held */
(void) start_subparse(0,0); /* Create empty CV in compcv. */
GV** gvp;
CV* cv;
const char *hvname;
+ HV* lastchance = NULL;
/* UNIVERSAL methods should be callable without a stash */
if (!stash) {
/* if at top level, try UNIVERSAL */
if (level == 0 || level == -1) {
- HV* const lastchance = gv_stashpvs("UNIVERSAL", FALSE);
+ lastchance = gv_stashpvs("UNIVERSAL", FALSE);
if (lastchance) {
if ((gv = gv_fetchmeth(lastchance, name, len,
sv_setpvn(varsv, packname, packname_len);
sv_catpvs(varsv, "::");
sv_catpvn(varsv, name, len);
- SvTAINTED_off(varsv);
return gv;
}
: sv_type == SVt_PVAV ? "@"
: sv_type == SVt_PVHV ? "%"
: ""), name);
+ GV *gv;
if (USE_UTF8_IN_NAMES)
SvUTF8_on(err);
qerror(err);
- stash = GvHV(gv_fetchpvn_flags("<none>::", 8, GV_ADDMULTI, SVt_PVHV));
+ gv = gv_fetchpvn_flags("<none>::", 8, GV_ADDMULTI, SVt_PVHV);
+ if(!gv) {
+ /* symbol table under destruction */
+ return NULL;
+ }
+ stash = GvHV(gv);
}
else
return NULL;
if (strEQ(name2, "RGV")) {
IoFLAGS(GvIOn(gv)) |= IOf_ARGV|IOf_START;
}
+ else if (strEQ(name2, "RGVOUT")) {
+ GvMULTI_on(gv);
+ }
break;
case 'E':
if (strnEQ(name2, "XPORT", 5))
goto magicalize;
case '+':
+ GvMULTI_on(gv);
{
AV* const av = GvAVn(gv);
+ HV* const hv = GvHVn(gv);
sv_magic((SV*)av, (SV*)av, PERL_MAGIC_regdata, NULL, 0);
SvREADONLY_on(av);
+ hv_magic(hv, NULL, PERL_MAGIC_regdata_names);
+ SvREADONLY_on(hv);
/* FALL THROUGH */
}
case '\023': /* $^S */
return;
}
- unshare_hek(gp->gp_file_hek);
+ if (gp->gp_file_hek)
+ unshare_hek(gp->gp_file_hek);
SvREFCNT_dec(gp->gp_sv);
SvREFCNT_dec(gp->gp_av);
/* FIXME - another reference loop GV -> symtab -> GV ?
*/
SV* const newref = newSVsv(tmpRef);
SvOBJECT_on(newref);
+ /* As a bit of a source compatibility hack, SvAMAGIC() and
+ friends dereference an RV, to behave the same was as when
+ overloading was stored on the reference, not the referant.
+ Hence we can't use SvAMAGIC_on()
+ */
+ SvFLAGS(newref) |= SVf_AMAGIC;
SvSTASH_set(newref, (HV*)SvREFCNT_inc(SvSTASH(tmpRef)));
return newref;
}
notfound = 1; lr = -1;
} else if (cvp && (cv=cvp[nomethod_amg])) {
notfound = 1; lr = 1;
+ } else if ((amtp && amtp->fallback >= AMGfallYES) && !DEBUG_o_TEST) {
+ /* Skip generating the "no method found" message. */
+ return NULL;
} else {
SV *msg;
if (off==-1) off=method;