}
SvUPGRADE(dstr, SVt_PVGV);
(void)SvOK_off(dstr);
- /* FIXME - why are we doing this, then turning it off and on again
- below? */
+ /* We have to turn this on here (even though we turn it off
+ below, as GvSTASH will fail an assertion otherwise. */
isGV_with_GP_on(dstr);
}
GvSTASH(dstr) = GvSTASH(sstr);
}
gp_free(MUTABLE_GV(dstr));
- isGV_with_GP_off(dstr);
+ isGV_with_GP_off(dstr); /* SvOK_off does not like globs. */
(void)SvOK_off(dstr);
isGV_with_GP_on(dstr);
GvINTRO_off(dstr); /* one-shot flag */
SvREADONLY_off(sv);
SvPV_set(sv, NULL);
SvLEN_set(sv, 0);
- SvGROW(sv, len + 1);
- Move(pvx,SvPVX(sv),len,char);
- *SvEND(sv) = '\0';
+ if (flags & SV_COW_DROP_PV) {
+ /* OK, so we don't need to copy our buffer. */
+ SvPOK_off(sv);
+ } else {
+ SvGROW(sv, len + 1);
+ Move(pvx,SvPVX(sv),len,char);
+ *SvEND(sv) = '\0';
+ }
unshare_hek(SvSHARED_HEK_FROM_PV(pvx));
}
else if (IN_PERL_RUNTIME)
if (SvROK(sv))
sv_unref_flags(sv, flags);
else if (SvFAKE(sv) && isGV_with_GP(sv))
- sv_unglob(sv);
+ sv_unglob(sv, flags);
else if (SvFAKE(sv) && SvTYPE(sv) == SVt_REGEXP) {
/* Need to downgrade the REGEXP to a simple(r) scalar. This is analogous
to sv_unglob. We only need it here, so inline it. */
=for apidoc sv_insert_flags
-Same as C<sv_insert>, but the extra C<flags> are passed the C<SvPV_force_flags> that applies to C<bigstr>.
+Same as C<sv_insert>, but the extra C<flags> are passed to the
+C<SvPV_force_flags> that applies to C<bigstr>.
=cut
*/
table. If the string does not already exist in the table, it is
created first. Turns on READONLY and FAKE. If the C<hash> parameter
is non-zero, that value is used; otherwise the hash is computed.
-The string's hash can be later be retrieved from the SV
+The string's hash can later be retrieved from the SV
with the C<SvSHARED_HASH()> macro. The idea here is
that as the string table is used for shared hash keys these strings will have
SvPVX_const == HeKEY and hash lookup will avoid string compare.
if (SvROK(sv)) {
if (SvAMAGIC(sv))
sv = amagic_deref_call(sv, to_cv_amg);
- /* At this point I'd like to do SPAGAIN, but really I need to
- force it upon my callers. Hmmm. This is a mess... */
sv = SvRV(sv);
if (SvTYPE(sv) == SVt_PVCV) {
PERL_ARGS_ASSERT_SV_PVN_FORCE_FLAGS;
+ if (flags & SV_GMAGIC) SvGETMAGIC(sv);
if (SvTHINKFIRST(sv) && !SvROK(sv))
sv_force_normal_flags(sv, 0);
/* diag_listed_as: Can't coerce %s to %s in %s */
Perl_croak(aTHX_ "Can't coerce %s to string in %s", sv_reftype(sv,0),
OP_DESC(PL_op));
- s = sv_2pv_flags(sv, &len, flags);
+ s = sv_2pv_flags(sv, &len, flags &~ SV_GMAGIC);
if (lp)
*lp = len;
* as it is after unglobbing it.
*/
-STATIC void
-S_sv_unglob(pTHX_ SV *const sv)
+PERL_STATIC_INLINE void
+S_sv_unglob(pTHX_ SV *const sv, U32 flags)
{
dVAR;
void *xpvmg;
assert(SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV);
SvFAKE_off(sv);
- gv_efullname3(temp, MUTABLE_GV(sv), "*");
+ if (!(flags & SV_COW_DROP_PV))
+ gv_efullname3(temp, MUTABLE_GV(sv), "*");
if (GvGP(sv)) {
if(GvCVu((const GV *)sv) && (stash = GvSTASH(MUTABLE_GV(sv)))
/* 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);
+ if (flags & SV_COW_DROP_PV) SvOK_off(sv);
+ else sv_setsv_flags(sv, temp, 0);
}
/*
* back into v-string notation and then let the
* vectorize happen normally
*/
- if (sv_derived_from(vecsv, "version")) {
+ if (sv_derived_from(vecsv, "version") && SvROK(vecsv)) {
char *version = savesvpv(vecsv);
if ( hv_exists(MUTABLE_HV(SvRV(vecsv)), "alpha", 5 ) ) {
Perl_warner(aTHX_ packWARN(WARN_INTERNAL),
break;
sv = hash ? MUTABLE_SV(GvHV(gv)): MUTABLE_SV(GvAV(gv));
}
- else /* @{expr}, %{expr} */
+ else if (obase == PL_op) /* @{expr}, %{expr} */
return find_uninit_var(cUNOPx(obase)->op_first,
uninit_sv, match);
+ else /* @{expr}, %{expr} as a sub-expression */
+ return NULL;
}
/* attempt to find a match within the aggregate */
if ( (type == OP_CONST && SvOK(cSVOPx_sv(kid)))
|| (type == OP_NULL && ! (kid->op_flags & OPf_KIDS))
|| (type == OP_PUSHMARK)
- || (
- /* @$a and %$a, but not @a or %a */
- (type == OP_RV2AV || type == OP_RV2HV)
- && cUNOPx(kid)->op_first
- && cUNOPx(kid)->op_first->op_type != OP_GV
- )
)
continue;
}