Skip to content

Commit

Permalink
Merge 5fa4652 into 3bbdeca
Browse files Browse the repository at this point in the history
  • Loading branch information
richardleach committed Aug 24, 2021
2 parents 3bbdeca + 5fa4652 commit 6cda1e0
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 9 deletions.
2 changes: 2 additions & 0 deletions embed.fnc
Expand Up @@ -1863,6 +1863,7 @@ poxX |void |sv_free2 |NN SV *const sv|const U32 refcnt
pd |void |sv_free_arenas
Apd |char* |sv_gets |NN SV *const sv|NN PerlIO *const fp|I32 append
Cpd |char* |sv_grow |NN SV *const sv|STRLEN newlen
Cpd |char* |sv_grow_fresh |NN SV *const sv|STRLEN newlen
Apd |void |sv_inc |NULLOK SV *const sv
Apd |void |sv_inc_nomg |NULLOK SV *const sv
ApMdb |void |sv_insert |NN SV *const bigstr|const STRLEN offset \
Expand Down Expand Up @@ -1922,6 +1923,7 @@ Apd |SV* |sv_setref_pvn |NN SV *const rv|NULLOK const char *const classname \
|NN const char *const pv|const STRLEN n
Apd |void |sv_setpv |NN SV *const sv|NULLOK const char *const ptr
Apd |void |sv_setpvn |NN SV *const sv|NULLOK const char *const ptr|const STRLEN len
Apd |void |sv_setpvn_fresh|NN SV *const sv|NULLOK const char *const ptr|const STRLEN len
Apd |char *|sv_setpv_bufsize|NN SV *const sv|const STRLEN cur|const STRLEN len
Xp |void |sv_sethek |NN SV *const sv|NULLOK const HEK *const hek
ApMdb |void |sv_setsv |NN SV *dsv|NULLOK SV *ssv
Expand Down
2 changes: 2 additions & 0 deletions embed.h
Expand Up @@ -615,6 +615,7 @@
#define sv_get_backrefs Perl_sv_get_backrefs
#define sv_gets(a,b,c) Perl_sv_gets(aTHX_ a,b,c)
#define sv_grow(a,b) Perl_sv_grow(aTHX_ a,b)
#define sv_grow_fresh(a,b) Perl_sv_grow_fresh(aTHX_ a,b)
#define sv_inc(a) Perl_sv_inc(aTHX_ a)
#define sv_inc_nomg(a) Perl_sv_inc_nomg(aTHX_ a)
#define sv_insert_flags(a,b,c,d,e,f) Perl_sv_insert_flags(aTHX_ a,b,c,d,e,f)
Expand Down Expand Up @@ -688,6 +689,7 @@
#define sv_setpviv_mg(a,b) Perl_sv_setpviv_mg(aTHX_ a,b)
#endif
#define sv_setpvn(a,b,c) Perl_sv_setpvn(aTHX_ a,b,c)
#define sv_setpvn_fresh(a,b,c) Perl_sv_setpvn_fresh(aTHX_ a,b,c)
#define sv_setpvn_mg(a,b,c) Perl_sv_setpvn_mg(aTHX_ a,b,c)
#define sv_setref_iv(a,b,c) Perl_sv_setref_iv(aTHX_ a,b,c)
#define sv_setref_nv(a,b,c) Perl_sv_setref_nv(aTHX_ a,b,c)
Expand Down
11 changes: 7 additions & 4 deletions pp_hot.c
Expand Up @@ -3097,7 +3097,6 @@ PP(pp_match)
EXTEND(SP, nparens + i);
EXTEND_MORTAL(nparens + i);
for (i = !i; i <= nparens; i++) {
PUSHs(sv_newmortal());
if (LIKELY((RXp_OFFS(prog)[i].start != -1)
&& RXp_OFFS(prog)[i].end != -1 ))
{
Expand All @@ -3112,9 +3111,13 @@ PP(pp_match)
"start=%ld, end=%ld, s=%p, strend=%p, len=%" UVuf,
(long) i, (long) RXp_OFFS(prog)[i].start,
(long)RXp_OFFS(prog)[i].end, s, strend, (UV) len);
sv_setpvn(*SP, s, len);
if (DO_UTF8(TARG) && is_utf8_string((U8*)s, len))
SvUTF8_on(*SP);
PUSHs(newSVpvn_flags(s, len,
(DO_UTF8(TARG) && is_utf8_string((U8*)s, len))
? SVf_UTF8|SVs_TEMP
: SVs_TEMP)
);
} else {
PUSHs(sv_newmortal());
}
}
if (global) {
Expand Down
2 changes: 1 addition & 1 deletion pp_sys.c
Expand Up @@ -4324,7 +4324,7 @@ PP(pp_system)
sv_2mortal(copysv);
if (SvPOK(origsv) || SvPOKp(origsv)) {
pv = SvPV_nomg(origsv, len);
sv_setpvn(copysv, pv, len);
sv_setpvn_fresh(copysv, pv, len);
SvPOK_off(copysv);
}
if (SvIOK(origsv) || SvIOKp(origsv))
Expand Down
6 changes: 6 additions & 0 deletions proto.h
Expand Up @@ -3546,6 +3546,9 @@ PERL_CALLCONV char* Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 appen
PERL_CALLCONV char* Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen);
#define PERL_ARGS_ASSERT_SV_GROW \
assert(sv)
PERL_CALLCONV char* Perl_sv_grow_fresh(pTHX_ SV *const sv, STRLEN newlen);
#define PERL_ARGS_ASSERT_SV_GROW_FRESH \
assert(sv)
PERL_CALLCONV void Perl_sv_inc(pTHX_ SV *const sv);
#define PERL_ARGS_ASSERT_SV_INC
PERL_CALLCONV void Perl_sv_inc_nomg(pTHX_ SV *const sv);
Expand Down Expand Up @@ -3791,6 +3794,9 @@ PERL_CALLCONV void Perl_sv_setpviv_mg(pTHX_ SV *const sv, const IV iv)
PERL_CALLCONV void Perl_sv_setpvn(pTHX_ SV *const sv, const char *const ptr, const STRLEN len);
#define PERL_ARGS_ASSERT_SV_SETPVN \
assert(sv)
PERL_CALLCONV void Perl_sv_setpvn_fresh(pTHX_ SV *const sv, const char *const ptr, const STRLEN len);
#define PERL_ARGS_ASSERT_SV_SETPVN_FRESH \
assert(sv)
PERL_CALLCONV void Perl_sv_setpvn_mg(pTHX_ SV *const sv, const char *const ptr, const STRLEN len);
#define PERL_ARGS_ASSERT_SV_SETPVN_MG \
assert(sv); assert(ptr)
Expand Down
96 changes: 92 additions & 4 deletions sv.c
Expand Up @@ -1625,6 +1625,59 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen)
return s;
}

/*
=for apidoc sv_grow_fresh

A cut-down version of sv_grow intended only for when sv is a freshly-minted
SVt_PV, SVt_PVIV, SVt_PVNV, or SVt_PVMG. i.e. sv has the default flags, has
never been any other type, and does not have an existing string. Basically,
just assigns a char buffer and returns a pointer to it.

=cut
*/


char *
Perl_sv_grow_fresh(pTHX_ SV *const sv, STRLEN newlen)
{
char *s;

PERL_ARGS_ASSERT_SV_GROW_FRESH;

assert(SvTYPE(sv) >= SVt_PV && SvTYPE(sv) <= SVt_PVMG);
assert(!SvROK(sv));
assert(!SvOOK(sv));
assert(!SvIsCOW(sv));
assert(!SvLEN(sv));
assert(!SvCUR(sv));

#ifdef PERL_COPY_ON_WRITE
/* the new COW scheme uses SvPVX(sv)[SvLEN(sv)-1] (if spare)
* to store the COW count. So in general, allocate one more byte than
* asked for, to make it likely this byte is always spare: and thus
* make more strings COW-able.
*
* Only increment if the allocation isn't MEM_SIZE_MAX,
* otherwise it will wrap to 0.
*/
if ( newlen != MEM_SIZE_MAX )
newlen++;
#endif

/* 10 is a longstanding, hardcoded minimum length in sv_grow. */
/* Just doing the same here for consistency. */
if (newlen < 10)
newlen = 10;

s = (char*)safemalloc(newlen);
SvPV_set(sv, s);

/* No PERL_UNWARANTED_CHUMMINESS_WITH_MALLOC here, since many strings */
/* will never be grown once set. Let the real sv_grow worry about that. */
SvLEN_set(sv, newlen);
return s;
}

/*
=for apidoc sv_setiv
=for apidoc_item sv_setiv_mg
Expand Down Expand Up @@ -4907,6 +4960,7 @@ Perl_sv_setpv_bufsize(pTHX_ SV *const sv, const STRLEN cur, const STRLEN len)

/*
=for apidoc sv_setpvn
=for apidoc sv_setpvn_fresh
=for apidoc_item sv_setpvn_mg

These copy a string (possibly containing embedded C<NUL> characters) into an
Expand All @@ -4921,6 +4975,10 @@ They differ only in that:

C<sv_setpvn> does not handle 'set' magic; C<sv_setpvn_mg> does.

C<sv_setpvn_fresh> is a cut-down alternative to C<sv_setpvn>, intended ONLY
to be used with a fresh sv that has been upgraded to a SVt_PV, SVt_PVIV,
SVt_PVNV, or SVt_PVMG.

=cut
*/

Expand Down Expand Up @@ -4965,6 +5023,32 @@ Perl_sv_setpvn_mg(pTHX_ SV *const sv, const char *const ptr, const STRLEN len)
SvSETMAGIC(sv);
}

void
Perl_sv_setpvn_fresh(pTHX_ SV *const sv, const char *const ptr, const STRLEN len)
{
char *dptr;

PERL_ARGS_ASSERT_SV_SETPVN_FRESH;
assert(SvTYPE(sv) >= SVt_PV && SvTYPE(sv) <= SVt_PVMG);
assert(!SvTHINKFIRST(sv));
assert(!isGV_with_GP(sv));

if (ptr) {
const IV iv = len;
/* len is STRLEN which is unsigned, need to copy to signed */
if (iv < 0)
Perl_croak(aTHX_ "panic: sv_setpvn_fresh called with negative strlen %"
IVdf, iv);

dptr = sv_grow_fresh(sv, len + 1);
Move(ptr,dptr,len,char);
dptr[len] = '\0';
SvCUR_set(sv, len);
SvPOK_on(sv);
SvTAINT(sv);
}
}

/*
=for apidoc sv_setpv
=for apidoc_item sv_setpv_mg
Expand Down Expand Up @@ -5650,7 +5734,8 @@ Perl_newSV(pTHX_ const STRLEN len)

new_SV(sv);
if (len) {
sv_grow(sv, len + 1);
sv_upgrade(sv, SVt_PV);
sv_grow_fresh(sv, len + 1);
}
return sv;
}
Expand Down Expand Up @@ -9308,7 +9393,8 @@ Perl_newSVpvn_flags(pTHX_ const char *const s, const STRLEN len, const U32 flags
And we're new code so I'm going to assert this from the start. */
assert(!(flags & ~(SVf_UTF8|SVs_TEMP)));
new_SV(sv);
sv_setpvn(sv,s,len);
sv_upgrade(sv, SVt_PV);
sv_setpvn_fresh(sv,s,len);

/* This code used to do a sv_2mortal(), however we now unroll the call to
* sv_2mortal() and do what it does ourselves here. Since we have asserted
Expand Down Expand Up @@ -9378,7 +9464,8 @@ Perl_newSVpv(pTHX_ const char *const s, const STRLEN len)
SV *sv;

new_SV(sv);
sv_setpvn(sv, s, len || s == NULL ? len : strlen(s));
sv_upgrade(sv, SVt_PV);
sv_setpvn_fresh(sv, s, len || s == NULL ? len : strlen(s));
return sv;
}

Expand All @@ -9400,7 +9487,8 @@ Perl_newSVpvn(pTHX_ const char *const buffer, const STRLEN len)
{
SV *sv;
new_SV(sv);
sv_setpvn(sv,buffer,len);
sv_upgrade(sv, SVt_PV);
sv_setpvn_fresh(sv,buffer,len);
return sv;
}

Expand Down

0 comments on commit 6cda1e0

Please sign in to comment.