summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-14 11:27:28 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-27 11:30:23 +0100
commit5febd2ff83ad8541c2fd1f43266e321d057ef865 (patch)
treee827e0dedfac367961b80c6a2d1c8fe34db8fc11 /pp.c
parentf446eca7ef7f31dd356f4dba9401fc3326be139c (diff)
downloadperl-5febd2ff83ad8541c2fd1f43266e321d057ef865.tar.gz
pp_length: code tidy and simplify assert
The STATIC_ASSERT_STMT() is basically checking that shifting the HINT_BYTES byte left 26 places gives you SVf_UTF8, so just assert that. There's no need to assert the current values of HINT_BYTES and SVf_UTF8. Other than that, this commit tides up the code a bit (only whitespace changes and unnecessary brace removal), and adds/updates some code comments.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/pp.c b/pp.c
index 016b7e82de..24326b8d63 100644
--- a/pp.c
+++ b/pp.c
@@ -3230,22 +3230,29 @@ PP(pp_oct)
/* String stuff. */
+
PP(pp_length)
{
dSP; dTARGET;
SV * const sv = TOPs;
U32 in_bytes = IN_BYTES;
- /* simplest case shortcut */
- /* turn off SVf_UTF8 in tmp flags if HINT_BYTES on*/
+ /* Simplest case shortcut:
+ * set svflags to just the SVf_POK|SVs_GMG|SVf_UTF8 from the SV,
+ * with the SVf_UTF8 flag inverted if under 'use bytes' (HINT_BYTES
+ * set)
+ */
U32 svflags = (SvFLAGS(sv) ^ (in_bytes << 26)) & (SVf_POK|SVs_GMG|SVf_UTF8);
- STATIC_ASSERT_STMT(HINT_BYTES == 0x00000008 && SVf_UTF8 == 0x20000000 && (SVf_UTF8 == HINT_BYTES << 26));
+
+ STATIC_ASSERT_STMT(SVf_UTF8 == (HINT_BYTES << 26));
SETs(TARG);
- if(LIKELY(svflags == SVf_POK))
+ if (LIKELY(svflags == SVf_POK))
goto simple_pv;
- if(svflags & SVs_GMG)
+
+ if (svflags & SVs_GMG)
mg_get(sv);
+
if (SvOK(sv)) {
STRLEN len;
if (!IN_BYTES) { /* reread to avoid using an C auto/register */
@@ -3253,30 +3260,34 @@ PP(pp_length)
goto simple_pv;
len = sv_len_utf8_nomg(sv);
}
- else
- {
+ else {
/* unrolled SvPV_nomg_const(sv,len) */
- if(SvPOK_nog(sv)){
- simple_pv:
+ if (SvPOK_nog(sv)) {
+ simple_pv:
len = SvCUR(sv);
- } else {
+ }
+ else {
(void)sv_2pv_flags(sv, &len, 0|SV_CONST_RETURN);
}
}
TARGi((IV)(len), 1);
- } else {
+ }
+ else {
if (!SvPADTMP(TARG)) {
+ /* OPpTARGET_MY: targ is var in '$lex = length()' */
sv_set_undef(TARG);
SvSETMAGIC(TARG);
- } else { /* TARG is on stack at this point and is overwriten by SETs.
- This branch is the odd one out, so put TARG by default on
- stack earlier to let local SP go out of liveness sooner */
+ }
+ else
+ /* TARG is on stack at this point and is overwriten by SETs.
+ * This branch is the odd one out, so put TARG by default on
+ * stack earlier to let local SP go out of liveness sooner */
SETs(&PL_sv_undef);
- }
}
return NORMAL; /* no putback, SP didn't move in this opcode */
}
+
/* Returns false if substring is completely outside original string.
No length is indicated by len_iv = 0 and len_is_uv = 0. len_is_uv must
always be true for an explicit 0.