p |int |magic_get |NN SV* sv|NN MAGIC* mg
p |int |magic_getarylen|NN SV* sv|NN const MAGIC* mg
p |int |magic_getdefelem|NN SV* sv|NN MAGIC* mg
-p |int |magic_getglob |NN SV* sv|NN MAGIC* mg
p |int |magic_getnkeys |NN SV* sv|NN MAGIC* mg
p |int |magic_getpack |NN SV* sv|NN MAGIC* mg
p |int |magic_getpos |NN SV* sv|NN MAGIC* mg
Apd |bool |sv_2bool |NN SV* sv
Apd |CV* |sv_2cv |NULLOK SV* sv|NN HV** st|NN GV** gvp|I32 lref
Apd |IO* |sv_2io |NN SV* sv
+#ifdef PERL_IN_SV_C
+s |char* |glob_2inpuv |NN GV* gv|NULLOK STRLEN *len|bool want_number
+#endif
Amb |IV |sv_2iv |NN SV* sv
Apd |IV |sv_2iv_flags |NN SV* sv|I32 flags
Apd |SV* |sv_2mortal |NULLOK SV* sv
#define magic_get Perl_magic_get
#define magic_getarylen Perl_magic_getarylen
#define magic_getdefelem Perl_magic_getdefelem
-#define magic_getglob Perl_magic_getglob
#define magic_getnkeys Perl_magic_getnkeys
#define magic_getpack Perl_magic_getpack
#define magic_getpos Perl_magic_getpos
#define sv_2bool Perl_sv_2bool
#define sv_2cv Perl_sv_2cv
#define sv_2io Perl_sv_2io
+#ifdef PERL_IN_SV_C
+#ifdef PERL_CORE
+#define glob_2inpuv S_glob_2inpuv
+#endif
+#endif
#define sv_2iv_flags Perl_sv_2iv_flags
#define sv_2mortal Perl_sv_2mortal
#define sv_2nv Perl_sv_2nv
#define magic_get(a,b) Perl_magic_get(aTHX_ a,b)
#define magic_getarylen(a,b) Perl_magic_getarylen(aTHX_ a,b)
#define magic_getdefelem(a,b) Perl_magic_getdefelem(aTHX_ a,b)
-#define magic_getglob(a,b) Perl_magic_getglob(aTHX_ a,b)
#define magic_getnkeys(a,b) Perl_magic_getnkeys(aTHX_ a,b)
#define magic_getpack(a,b) Perl_magic_getpack(aTHX_ a,b)
#define magic_getpos(a,b) Perl_magic_getpos(aTHX_ a,b)
#define sv_2bool(a) Perl_sv_2bool(aTHX_ a)
#define sv_2cv(a,b,c,d) Perl_sv_2cv(aTHX_ a,b,c,d)
#define sv_2io(a) Perl_sv_2io(aTHX_ a)
+#ifdef PERL_IN_SV_C
+#ifdef PERL_CORE
+#define glob_2inpuv(a,b,c) S_glob_2inpuv(aTHX_ a,b,c)
+#endif
+#endif
#define sv_2iv_flags(a,b) Perl_sv_2iv_flags(aTHX_ a,b)
#define sv_2mortal(a) Perl_sv_2mortal(aTHX_ a)
#define sv_2nv(a) Perl_sv_2nv(aTHX_ a)
*a,
'SV = PVGV\\($ADDR\\) at $ADDR
REFCNT = 5
- FLAGS = \\(GMG,SMG,MULTI(?:,IN_PAD)?\\)
+ FLAGS = \\(SMG,SCREAM,MULTI(?:,IN_PAD)?\\)
IV = 0
NV = 0
PV = 0
GvCVGEN(gv) = 0;
GvEGV(gv) = gv;
sv_magic((SV*)gv, (SV*)gv, PERL_MAGIC_glob, NULL, 0);
+ SvSCREAM_on(gv);
GvSTASH(gv) = stash;
if (stash)
Perl_sv_add_backref(aTHX_ (SV*)stash, (SV*)gv);
}
int
-Perl_magic_getglob(pTHX_ SV *sv, MAGIC *mg)
-{
- const U32 wasfake = SvFLAGS(sv) & SVf_FAKE;
- PERL_UNUSED_ARG(mg);
-
- /* FAKE globs can get coerced, so need to turn this off temporarily if it
- is on. */
- SvFAKE_off(sv);
- gv_efullname3(sv,((GV*)sv), "*");
- SvFLAGS(sv) |= wasfake;
-
- return 0;
-}
-
-int
Perl_magic_setglob(pTHX_ SV *sv, MAGIC *mg)
{
GV* gv;
if (!SvOK(sv))
return 0;
+ if (SvFLAGS(sv) & SVp_SCREAM
+ && (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVGV)) {
+ /* We're actually already a typeglob, so don't need the stuff below.
+ */
+ return 0;
+ }
gv = gv_fetchsv(sv, GV_ADD, SVt_PVGV);
if (sv == (SV*)gv)
return 0;
MGVTBL_SET(
PL_vtbl_glob,
- MEMBER_TO_FPTR(Perl_magic_getglob),
+ NULL,
MEMBER_TO_FPTR(Perl_magic_setglob),
NULL,
NULL,
__attribute__nonnull__(pTHX_1)
__attribute__nonnull__(pTHX_2);
-PERL_CALLCONV int Perl_magic_getglob(pTHX_ SV* sv, MAGIC* mg)
- __attribute__nonnull__(pTHX_1)
- __attribute__nonnull__(pTHX_2);
-
PERL_CALLCONV int Perl_magic_getnkeys(pTHX_ SV* sv, MAGIC* mg)
__attribute__nonnull__(pTHX_1)
__attribute__nonnull__(pTHX_2);
PERL_CALLCONV IO* Perl_sv_2io(pTHX_ SV* sv)
__attribute__nonnull__(pTHX_1);
+#ifdef PERL_IN_SV_C
+STATIC char* S_glob_2inpuv(pTHX_ GV* gv, STRLEN *len, bool want_number)
+ __attribute__nonnull__(pTHX_1);
+
+#endif
/* PERL_CALLCONV IV sv_2iv(pTHX_ SV* sv)
__attribute__nonnull__(pTHX_1); */
return grok_number(sbegin, len, NULL);
}
+STATIC char *
+S_glob_2inpuv(pTHX_ GV *gv, STRLEN *len, bool want_number)
+{
+ const U32 wasfake = SvFLAGS(gv) & SVf_FAKE;
+ SV *const buffer = sv_newmortal();
+
+ /* FAKE globs can get coerced, so need to turn this off temporarily if it
+ is on. */
+ SvFAKE_off(gv);
+ gv_efullname3(buffer, gv, "*");
+ SvFLAGS(gv) |= wasfake;
+
+ if (want_number) {
+ /* We know that all GVs stringify to something that is not-a-number,
+ so no need to test that. */
+ if (ckWARN(WARN_NUMERIC))
+ not_a_number(buffer);
+ /* We just want something true to return, so that S_sv_2iuv_common
+ can tail call us and return true. */
+ return (char *) 1;
+ } else {
+ return SvPV(buffer, *len);
+ }
+}
+
/* Actually, ISO C leaves conversion of UV to IV undefined, but
until proven guilty, assume that things are not that bad... */
}
}
else {
+ if (((SvFLAGS(sv) & (SVp_POK|SVp_SCREAM)) == SVp_SCREAM)
+ && (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV)) {
+ return PTR2IV(glob_2inpuv((GV *)sv, NULL, TRUE));
+ }
+ if (SvTYPE(sv) == SVt_PVGV)
+ sv_dump(sv);
+
if (!(SvFLAGS(sv) & SVs_PADTMP)) {
if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
#endif /* NV_PRESERVES_UV */
}
else {
+ if (((SvFLAGS(sv) & (SVp_POK|SVp_SCREAM)) == SVp_SCREAM)
+ && (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV)) {
+ glob_2inpuv((GV *)sv, NULL, TRUE);
+ return 0.0;
+ }
+
if (!PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP) && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
assert (SvTYPE(sv) >= SVt_NV);
#endif
}
else {
+ if (((SvFLAGS(sv) & (SVp_POK|SVp_SCREAM)) == SVp_SCREAM)
+ && (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV)) {
+ return glob_2inpuv((GV *)sv, lp, FALSE);
+ }
+
if (!PL_localizing && !(SvFLAGS(sv) & SVs_PADTMP) && ckWARN(WARN_UNINITIALIZED))
report_uninit(sv);
if (lp)
else {
if (SvNOKp(sv))
return SvNVX(sv) != 0.0;
- else
- return FALSE;
+ else {
+ if ((SvFLAGS(sv) & SVp_SCREAM)
+ && (SvTYPE(sv) == (SVt_PVGV) || SvTYPE(sv) == (SVt_PVLV)))
+ return TRUE;
+ else
+ return FALSE;
+ }
}
}
}
#endif
(void)SvOK_off(dstr);
+ SvSCREAM_on(dstr);
GvINTRO_off(dstr); /* one-shot flag */
gp_free((GV*)dstr);
GvGP(dstr) = gp_ref(GvGP(sstr));
if (ckWARN(WARN_MISC))
Perl_warner(aTHX_ packWARN(WARN_MISC), "Undefined value assigned to typeglob");
}
+ else if ((stype == SVt_PVGV || stype == SVt_PVLV)
+ && (sflags & SVp_SCREAM)) {
+ /* This stringification rule for globs is spread in 3 places.
+ This feels bad. FIXME. */
+ const U32 wasfake = sflags & SVf_FAKE;
+
+ /* FAKE globs can get coerced, so need to turn this off
+ temporarily if it is on. */
+ SvFAKE_off(sstr);
+ gv_efullname3(dstr, (GV *)sstr, "*");
+ SvFLAGS(sstr) |= wasfake;
+ }
else
(void)SvOK_off(dstr);
}
{
dVAR;
void *xpvmg;
+ SV *temp = sv_newmortal();
assert(SvTYPE(sv) == SVt_PVGV);
SvFAKE_off(sv);
+ gv_efullname3(temp, (GV *) sv, "*");
+
if (GvGP(sv))
gp_free((GV*)sv);
if (GvSTASH(sv)) {
GvSTASH(sv) = NULL;
}
sv_unmagic(sv, PERL_MAGIC_glob);
+ SvSCREAM_off(sv);
Safefree(GvNAME(sv));
GvMULTI_off(sv);
SvFLAGS(sv) &= ~SVTYPEMASK;
SvFLAGS(sv) |= SVt_PVMG;
+
+ /* Intentionally not calling any local SET magic, as this isn't so much a
+ set operation as merely an internal storage change. */
+ sv_setsv_flags(sv, temp, 0);
}
/*
#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE)
#define SVf_OK (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \
- SVp_IOK|SVp_NOK|SVp_POK)
+ SVp_IOK|SVp_NOK|SVp_POK|SVp_SCREAM)
#define PRIVSHIFT 4 /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */
#define SvREADONLY_on(sv) (SvFLAGS(sv) |= SVf_READONLY)
#define SvREADONLY_off(sv) (SvFLAGS(sv) &= ~SVf_READONLY)
-#define SvSCREAM(sv) (SvFLAGS(sv) & SVp_SCREAM)
+#define SvSCREAM(sv) ((SvFLAGS(sv) & (SVp_SCREAM|SVp_POK)) == (SVp_SCREAM|SVp_POK))
#define SvSCREAM_on(sv) (SvFLAGS(sv) |= SVp_SCREAM)
#define SvSCREAM_off(sv) (SvFLAGS(sv) &= ~SVp_SCREAM)