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;
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;
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;
/* 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().
*
{
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)
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);
}
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;
}
/*