In perl.git, the branch blead has been updated <https://perl5.git.perl.org/perl.git/commitdiff/ca84e88ece180337b1ea0b8a2b9d4211b1089878?hp=bc60657c80df1e21e2a12017077425d3b6db6cfe>
- Log ----------------------------------------------------------------- commit ca84e88ece180337b1ea0b8a2b9d4211b1089878 Author: David Mitchell <[email protected]> Date: Mon Nov 13 11:50:14 2017 +0000 change OP_MULTICONCAT nargs from UV to SSize_t Change it from unsigned to unsigned since it makes the SP-adjusting code in pp_multiconcat easier without hitting undefined behaviour (RT #132390); and change its size from UV to SSize_t since it represents the number of args on the stack. commit b5bf9f73a7cc9feabf29609f45df824fed127956 Author: David Mitchell <[email protected]> Date: Mon Nov 13 11:03:15 2017 +0000 rename op_aux field from 'size' to 'ssize' This part of the op_aux union was added for OP_MULTICONCAT; its actually of type SSize_t, so rename it to ssize to better reflect that it's signed. This should make no functional difference. ----------------------------------------------------------------------- Summary of changes: dump.c | 17 ++++++++--------- ext/B/B.xs | 14 +++++++------- op.c | 36 ++++++++++++++++++------------------ op.h | 2 +- pp_hot.c | 32 ++++++++++++++++---------------- 5 files changed, 50 insertions(+), 51 deletions(-) diff --git a/dump.c b/dump.c index bf01207e24..b2f0fc5ef2 100644 --- a/dump.c +++ b/dump.c @@ -1142,8 +1142,8 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o) } case OP_MULTICONCAT: - S_opdump_indent(aTHX_ o, level, bar, file, "NARGS = %" UVuf "\n", - cUNOP_AUXo->op_aux[PERL_MULTICONCAT_IX_NARGS].uv); + S_opdump_indent(aTHX_ o, level, bar, file, "NARGS = %" IVdf "\n", + (IV)cUNOP_AUXo->op_aux[PERL_MULTICONCAT_IX_NARGS].ssize); /* XXX really ought to dump each field individually, * but that's too much like hard work */ S_opdump_indent(aTHX_ o, level, bar, file, "CONSTS = (%" SVf ")\n", @@ -2749,18 +2749,18 @@ Perl_multiconcat_stringify(pTHX_ const OP *o) UNOP_AUX_item *aux = cUNOP_AUXo->op_aux; UNOP_AUX_item *lens; STRLEN len; - UV nargs; + SSize_t nargs; char *s; SV *out = newSVpvn_flags("", 0, SVs_TEMP); PERL_ARGS_ASSERT_MULTICONCAT_STRINGIFY; - nargs = aux[PERL_MULTICONCAT_IX_NARGS].uv; + nargs = aux[PERL_MULTICONCAT_IX_NARGS].ssize; s = aux[PERL_MULTICONCAT_IX_PLAIN_PV].pv; - len = aux[PERL_MULTICONCAT_IX_PLAIN_LEN].size; + len = aux[PERL_MULTICONCAT_IX_PLAIN_LEN].ssize; if (!s) { s = aux[PERL_MULTICONCAT_IX_UTF8_PV].pv; - len = aux[PERL_MULTICONCAT_IX_UTF8_LEN].size; + len = aux[PERL_MULTICONCAT_IX_UTF8_LEN].ssize; sv_catpvs(out, "UTF8 "); } pv_pretty(out, s, len, 50, @@ -2770,9 +2770,8 @@ Perl_multiconcat_stringify(pTHX_ const OP *o) |PERL_PV_PRETTY_ELLIPSES)); lens = aux + PERL_MULTICONCAT_IX_LENGTHS; - nargs++; - while (nargs-- > 0) { - Perl_sv_catpvf(aTHX_ out, ",%" IVdf, (IV)lens->size); + while (nargs-- >= 0) { + Perl_sv_catpvf(aTHX_ out, ",%" IVdf, (IV)lens->ssize); lens++; } return out; diff --git a/ext/B/B.xs b/ext/B/B.xs index fc36a36054..a22b02ffed 100644 --- a/ext/B/B.xs +++ b/ext/B/B.xs @@ -1244,7 +1244,7 @@ aux_list(o, cv) case OP_MULTICONCAT: { - UV nargs = aux[0].uv; + SSize_t nargs; char *p; STRLEN len; U32 utf8 = 0; @@ -1255,15 +1255,15 @@ aux_list(o, cv) /* if this changes, this block of code probably needs fixing */ assert(PERL_MULTICONCAT_HEADER_SIZE == 5); - nargs = aux[PERL_MULTICONCAT_IX_NARGS].uv; + nargs = aux[PERL_MULTICONCAT_IX_NARGS].ssize; EXTEND(SP, ((SSize_t)(2 + (nargs+1)))); - PUSHs(sv_2mortal(newSViv(nargs))); + PUSHs(sv_2mortal(newSViv((IV)nargs))); p = aux[PERL_MULTICONCAT_IX_PLAIN_PV].pv; - len = aux[PERL_MULTICONCAT_IX_PLAIN_LEN].size; + len = aux[PERL_MULTICONCAT_IX_PLAIN_LEN].ssize; if (!p) { p = aux[PERL_MULTICONCAT_IX_UTF8_PV].pv; - len = aux[PERL_MULTICONCAT_IX_UTF8_LEN].size; + len = aux[PERL_MULTICONCAT_IX_UTF8_LEN].ssize; utf8 = SVf_UTF8; } sv = newSVpvn(p, len); @@ -1275,7 +1275,7 @@ aux_list(o, cv) if (utf8) { U8 *p = (U8*)SvPVX(sv); while (nargs--) { - SSize_t bytes = lens->size; + SSize_t bytes = lens->ssize; SSize_t chars; if (bytes <= 0) chars = bytes; @@ -1290,7 +1290,7 @@ aux_list(o, cv) } else { while (nargs--) { - PUSHs(sv_2mortal(newSViv(lens->size))); + PUSHs(sv_2mortal(newSViv(lens->ssize))); lens++; } } diff --git a/op.c b/op.c index 15fe1afb0e..befef7cc5d 100644 --- a/op.c +++ b/op.c @@ -2489,7 +2489,7 @@ S_check_hash_fields_and_hekify(pTHX_ UNOP *rop, SVOP *key_op) /* info returned by S_sprintf_is_multiconcatable() */ struct sprintf_ismc_info { - UV nargs; /* num of args to sprintf (not including the format) */ + SSize_t nargs; /* num of args to sprintf (not including the format) */ char *start; /* start of raw format string */ char *end; /* bytes after end of raw format string */ STRLEN total_len; /* total length (in bytes) of format string, not @@ -2517,7 +2517,7 @@ S_sprintf_is_multiconcatable(pTHX_ OP *o,struct sprintf_ismc_info *info) OP *pm, *constop, *kid; SV *sv; char *s, *e, *p; - UV nargs, nformats; + SSize_t nargs, nformats; STRLEN cur, total_len, variant; bool utf8; @@ -2660,8 +2660,8 @@ S_maybe_multiconcat(pTHX_ OP *o) STRLEN len; /* ... len set to SvPV(..., len) */ } *argp, *toparg, args[PERL_MULTICONCAT_MAXARG*2 + 1]; - UV nargs = 0; - UV nconst = 0; + SSize_t nargs = 0; + SSize_t nconst = 0; STRLEN variant; bool utf8 = FALSE; bool kid_is_last = FALSE; /* most args will be the RHS kid of a concat op; @@ -3095,14 +3095,14 @@ S_maybe_multiconcat(pTHX_ OP *o) if (*p == '%') { p++; if (*p != '%') { - (lenp++)->size = q - oldq; + (lenp++)->ssize = q - oldq; oldq = q; continue; } } *q++ = *p; } - lenp->size = q - oldq; + lenp->ssize = q - oldq; assert((STRLEN)(q - const_str) == total_len); /* Attach all the args (i.e. the kids of the sprintf) to o (which @@ -3123,7 +3123,7 @@ S_maybe_multiconcat(pTHX_ OP *o) p = const_str; lenp = aux + PERL_MULTICONCAT_IX_LENGTHS; - lenp->size = -1; + lenp->ssize = -1; /* Concatenate all const strings into const_str. * Note that args[] contains the RHS args in reverse order, so @@ -3133,15 +3133,15 @@ S_maybe_multiconcat(pTHX_ OP *o) for (argp = toparg; argp >= args; argp--) { if (!argp->p) /* not a const op */ - (++lenp)->size = -1; + (++lenp)->ssize = -1; else { STRLEN l = argp->len; Copy(argp->p, p, l, char); p += l; - if (lenp->size == -1) - lenp->size = l; + if (lenp->ssize == -1) + lenp->ssize = l; else - lenp->size += l; + lenp->ssize += l; } } @@ -3215,11 +3215,11 @@ S_maybe_multiconcat(pTHX_ OP *o) /* Populate the aux struct */ - aux[PERL_MULTICONCAT_IX_NARGS].uv = nargs; + aux[PERL_MULTICONCAT_IX_NARGS].ssize = nargs; aux[PERL_MULTICONCAT_IX_PLAIN_PV].pv = utf8 ? NULL : const_str; - aux[PERL_MULTICONCAT_IX_PLAIN_LEN].size = utf8 ? 0 : total_len; + aux[PERL_MULTICONCAT_IX_PLAIN_LEN].ssize = utf8 ? 0 : total_len; aux[PERL_MULTICONCAT_IX_UTF8_PV].pv = const_str; - aux[PERL_MULTICONCAT_IX_UTF8_LEN].size = total_len; + aux[PERL_MULTICONCAT_IX_UTF8_LEN].ssize = total_len; /* if variant > 0, calculate a variant const string and lengths where * the utf8 version of the string will take 'variant' more bytes than @@ -3231,19 +3231,19 @@ S_maybe_multiconcat(pTHX_ OP *o) UNOP_AUX_item *lens = aux + PERL_MULTICONCAT_IX_LENGTHS; UNOP_AUX_item *ulens = lens + (nargs + 1); char *up = (char*)PerlMemShared_malloc(ulen); - UV n; + SSize_t n; aux[PERL_MULTICONCAT_IX_UTF8_PV].pv = up; - aux[PERL_MULTICONCAT_IX_UTF8_LEN].size = ulen; + aux[PERL_MULTICONCAT_IX_UTF8_LEN].ssize = ulen; for (n = 0; n < (nargs + 1); n++) { SSize_t i; char * orig_up = up; - for (i = (lens++)->size; i > 0; i--) { + for (i = (lens++)->ssize; i > 0; i--) { U8 c = *p++; append_utf8_from_native_byte(c, (U8**)&up); } - (ulens++)->size = (i < 0) ? i : up - orig_up; + (ulens++)->ssize = (i < 0) ? i : up - orig_up; } } diff --git a/op.h b/op.h index 513fc655fd..eb62c946fc 100644 --- a/op.h +++ b/op.h @@ -189,7 +189,7 @@ typedef union { IV iv; UV uv; char *pv; - SSize_t size; + SSize_t ssize; } UNOP_AUX_item; #ifdef USE_ITHREADS diff --git a/pp_hot.c b/pp_hot.c index d980db837c..4f1047d300 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -391,8 +391,8 @@ PP(pp_multiconcat) UNOP_AUX_item *aux; /* PL_op->op_aux buffer */ UNOP_AUX_item *const_lens; /* the segment length array part of aux */ const char *const_pv; /* the current segment of the const string buf */ - UV nargs; /* how many args were expected */ - UV stack_adj; /* how much to adjust SP on return */ + SSize_t nargs; /* how many args were expected */ + SSize_t stack_adj; /* how much to adjust SP on return */ STRLEN grow; /* final size of destination string (dsv) */ UV targ_count; /* how many times targ has appeared on the RHS */ bool is_append; /* OPpMULTICONCAT_APPEND flag is set */ @@ -412,7 +412,7 @@ PP(pp_multiconcat) svpv_buf[PERL_MULTICONCAT_MAXARG]; /* buf for storing SvPV() results */ aux = cUNOP_AUXx(PL_op)->op_aux; - stack_adj = nargs = aux[PERL_MULTICONCAT_IX_NARGS].uv; + stack_adj = nargs = aux[PERL_MULTICONCAT_IX_NARGS].ssize; is_append = cBOOL(PL_op->op_private & OPpMULTICONCAT_APPEND); /* get targ from the stack or pad */ @@ -523,8 +523,8 @@ PP(pp_multiconcat) if ( svpv_end == svpv_buf + 1 /* no const string segments */ - && aux[PERL_MULTICONCAT_IX_LENGTHS].size == -1 - && aux[PERL_MULTICONCAT_IX_LENGTHS + 1].size == -1 + && aux[PERL_MULTICONCAT_IX_LENGTHS].ssize == -1 + && aux[PERL_MULTICONCAT_IX_LENGTHS + 1].ssize == -1 ) { /* special case: if the overloaded sv is the * second arg in the concat chain, stop at the @@ -588,8 +588,8 @@ PP(pp_multiconcat) && is_append && nargs == 1 /* no const string segments */ - && aux[PERL_MULTICONCAT_IX_LENGTHS].size == -1 - && aux[PERL_MULTICONCAT_IX_LENGTHS+1].size == -1) + && aux[PERL_MULTICONCAT_IX_LENGTHS].ssize == -1 + && aux[PERL_MULTICONCAT_IX_LENGTHS+1].ssize == -1) { /* special-case $tied .= $tied. * @@ -779,7 +779,7 @@ PP(pp_multiconcat) { SSize_t len; len = aux[dst_utf8 ? PERL_MULTICONCAT_IX_UTF8_LEN - : PERL_MULTICONCAT_IX_PLAIN_LEN].size; + : PERL_MULTICONCAT_IX_PLAIN_LEN].ssize; slow_concat = cBOOL(len); grow += len; } @@ -888,7 +888,7 @@ PP(pp_multiconcat) UNOP_AUX_item *lens = const_lens; /* length of first const string segment */ - STRLEN offset = lens->size > 0 ? lens->size : 0; + STRLEN offset = lens->ssize > 0 ? lens->ssize : 0; assert(targ_chain); svpv_p = svpv_base; @@ -902,7 +902,7 @@ PP(pp_multiconcat) if (len < 0) /* variant args have this */ len = -len; offset += (STRLEN)len; - len = (++lens)->size; + len = (++lens)->ssize; offset += (len >= 0) ? (STRLEN)len : 0; if (!offset) { /* all args and consts so far are empty; update @@ -979,7 +979,7 @@ PP(pp_multiconcat) svpv_p = svpv_base - 1; for (;;) { - SSize_t len = (const_lens++)->size; + SSize_t len = (const_lens++)->ssize; /* append next const string segment */ if (len > 0) { @@ -1049,14 +1049,14 @@ PP(pp_multiconcat) bool getmg = FALSE; SV *constsv = NULL; /* number of args already concatted */ - STRLEN n = (nargs - 1) - (toparg - SP); + SSize_t n = (nargs - 1) - (toparg - SP); /* current arg is either the first * or second value to be concatted * (including constant strings), so would * form part of the first concat */ bool first_concat = ( n == 0 - || (n == 1 && const_lens[-2].size < 0 - && const_lens[-1].size < 0)); + || (n == 1 && const_lens[-2].ssize < 0 + && const_lens[-1].ssize < 0)); int f_assign = first_concat ? 0 : AMGf_assign; left = dsv; @@ -1066,7 +1066,7 @@ PP(pp_multiconcat) for (i = 0; i < 2; i++) { if (i) { /* append next const string segment */ - STRLEN len = (STRLEN)((const_lens++)->size); + STRLEN len = (STRLEN)((const_lens++)->ssize); /* a length of -1 implies no constant string * rather than a zero-length one, e.g. * ($a . $b) versus ($a . "" . $b) @@ -1099,7 +1099,7 @@ PP(pp_multiconcat) * before we broke from the loop earlier */ getmg = TRUE; - if (first_concat && n == 0 && const_lens[-1].size < 0) { + if (first_concat && n == 0 && const_lens[-1].ssize < 0) { /* nothing before the current arg; repeat the * loop to get a second arg */ left = right; -- Perl5 Master Repository
