X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/a223205704cce2b45732f255cf3856f1301b3850..354810ee5b030780b7036ad80d5adf09f6dcb317:/doop.c diff --git a/doop.c b/doop.c index d0ee927..2294281 100644 --- a/doop.c +++ b/doop.c @@ -323,15 +323,9 @@ S_do_trans_simple_utf8(pTHX_ SV * const sv) s = (U8*)SvPV_nomg(sv, len); if (!SvUTF8(sv)) { - const U8 *t = s; - const U8 * const e = s + len; - while (t < e) { - const U8 ch = *t++; - hibit = !NATIVE_BYTE_IS_INVARIANT(ch); - if (hibit) { - s = bytes_to_utf8(s, &len); - break; - } + hibit = ! is_utf8_invariant_string(s, len); + if (hibit) { + s = bytes_to_utf8(s, &len); } } send = s + len; @@ -423,15 +417,9 @@ S_do_trans_count_utf8(pTHX_ SV * const sv) s = (const U8*)SvPV_nomg_const(sv, len); if (!SvUTF8(sv)) { - const U8 *t = s; - const U8 * const e = s + len; - while (t < e) { - const U8 ch = *t++; - hibit = !NATIVE_BYTE_IS_INVARIANT(ch); - if (hibit) { - start = s = bytes_to_utf8(s, &len); - break; - } + hibit = ! is_utf8_invariant_string(s, len); + if (hibit) { + start = s = bytes_to_utf8(s, &len); } } send = s + len; @@ -477,15 +465,9 @@ S_do_trans_complex_utf8(pTHX_ SV * const sv) PERL_ARGS_ASSERT_DO_TRANS_COMPLEX_UTF8; if (!SvUTF8(sv)) { - const U8 *t = s; - const U8 * const e = s + len; - while (t < e) { - const U8 ch = *t++; - hibit = !NATIVE_BYTE_IS_INVARIANT(ch); - if (hibit) { - s = bytes_to_utf8(s, &len); - break; - } + hibit = ! is_utf8_invariant_string(s, len); + if (hibit) { + s = bytes_to_utf8(s, &len); } } send = s + len; @@ -1243,8 +1225,6 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right) /* Perl_do_kv() may be: * * called directly as the pp function for pp_keys() and pp_values(); - * * called indirectly by pp_padhv() and pp_rv2hv() to implement their - * key-value list context functionality. * * It may also be called directly when the op is OP_AVHVSWITCH, to * implement CORE::keys(), CORE::values(). * @@ -1257,29 +1237,25 @@ Perl_do_kv(pTHX) { dSP; HV * const keys = MUTABLE_HV(POPs); - HE *entry; - SSize_t extend_size; const U8 gimme = GIMME_V; - const I32 dokv = ( PL_op->op_type == OP_RV2HV - || PL_op->op_type == OP_PADHV); - - const I32 dokeys = dokv - || (PL_op->op_type == OP_KEYS) + const I32 dokeys = (PL_op->op_type == OP_KEYS) || ( PL_op->op_type == OP_AVHVSWITCH - && (PL_op->op_private & 3) + OP_EACH == OP_KEYS); + && (PL_op->op_private & OPpAVHVSWITCH_MASK) + + OP_EACH == OP_KEYS); - const I32 dovalues = dokv - || (PL_op->op_type == OP_VALUES) + const I32 dovalues = (PL_op->op_type == OP_VALUES) || ( PL_op->op_type == OP_AVHVSWITCH - && (PL_op->op_private & 3) + OP_EACH == OP_VALUES); + && (PL_op->op_private & OPpAVHVSWITCH_MASK) + + OP_EACH == OP_VALUES); - assert( PL_op->op_type == OP_PADHV - || PL_op->op_type == OP_RV2HV - || PL_op->op_type == OP_KEYS + assert( PL_op->op_type == OP_KEYS || PL_op->op_type == OP_VALUES || PL_op->op_type == OP_AVHVSWITCH); + assert(!( PL_op->op_type == OP_VALUES + && (PL_op->op_private & OPpMAYBE_LVSUB))); + (void)hv_iterinit(keys); /* always reset iterator regardless */ if (gimme == G_VOID) @@ -1297,6 +1273,11 @@ Perl_do_kv(pTHX) IV i; dTARGET; + /* note that in 'scalar(keys %h)' the OP_KEYS is usually + * optimised away and the action is performed directly by the + * padhv or rv2hv op. We now only get here via OP_AVHVSWITCH + * and \&CORE::keys + */ if (! SvTIED_mg((const SV *)keys, PERL_MAGIC_tied) ) { i = HvUSEDKEYS(keys); } @@ -1316,22 +1297,9 @@ Perl_do_kv(pTHX) Perl_croak(aTHX_ "Can't modify keys in list assignment"); } - /* 2*HvUSEDKEYS() should never be big enough to truncate or wrap */ - assert(HvUSEDKEYS(keys) <= (SSize_t_MAX >> 1)); - extend_size = (SSize_t)HvUSEDKEYS(keys) * (dokeys + dovalues); - EXTEND(SP, extend_size); - - while ((entry = hv_iternext(keys))) { - if (dokeys) { - SV* const sv = hv_iterkeysv(entry); - XPUSHs(sv); - } - if (dovalues) { - SV *const sv = hv_iterval(keys,entry); - XPUSHs(sv); - } - } - RETURN; + PUTBACK; + hv_pushkv(keys, (dokeys | (dovalues << 1))); + return NORMAL; } /*