{
dVAR;
register GP *gp;
- const bool doproto = SvTYPE(gv) > SVt_NULL;
+ const U32 old_type = SvTYPE(gv);
+ 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;
SvROK_off(gv);
}
- sv_upgrade((SV*)gv, SVt_PVGV);
+
+ if (old_type < SVt_PVGV) {
+ if (old_type >= SVt_PV)
+ SvCUR_set(gv, 0);
+ sv_upgrade((SV*)gv, SVt_PVGV);
+ }
if (SvLEN(gv)) {
if (proto) {
SvPV_set(gv, NULL);
GvSTASH(gv) = stash;
if (stash)
Perl_sv_add_backref(aTHX_ (SV*)stash, (SV*)gv);
- GvNAME(gv) = savepvn(name, len);
- GvNAMELEN(gv) = len;
+ gv_name_set(gv, name, len, GV_ADD);
if (multi || doproto) /* doproto means it _was_ mentioned */
GvMULTI_on(gv);
if (doproto) { /* Replicate part of newSUB here. */
return FALSE;
}
+void
+Perl_gv_name_set(pTHX_ GV *gv, const char *name, U32 len, U32 flags)
+{
+ dVAR;
+ U32 hash;
+
+ PERL_UNUSED_ARG(flags);
+
+ if (len > I32_MAX)
+ Perl_croak(aTHX_ "panic: gv name too long (%"UVuf")", (UV) len);
+
+ if (!(flags & GV_ADD) && GvNAME_HEK(gv)) {
+ unshare_hek(GvNAME_HEK(gv));
+ }
+
+ PERL_HASH(hash, name, len);
+ GvNAME_HEK(gv) = name ? share_hek(name, len, hash) : 0;
+}
+
/*
* Local variables:
* c-indentation-style: bsd