Centralize ISASCII early exit for search_nonascii (#17166)

This commit is contained in:
FletcherDares authored and GitHub committed 2026-06-02 13:45:55 +09:00
1 parent 325228e2b8
commit 056ae1f926
2 files changed
+42 -42
Notes: git 2026-06-02 04:46:24 +00:00
Merged-By: ioquatix <samuel@codeotaku.com>

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
prelude: |
def unknown(s) = s.b.force_encoding("UTF-8")
multibyte = unknown("\u{00e9}" * 16384) # best case: every byte non-ASCII
alternating = unknown("\u{00e9}a" * 10922) # worst case: non-ASCII then ASCII
ascii = unknown("a" * 32768) # baseline
benchmark:
coderange_multibyte: multibyte.dup.valid_encoding?
coderange_alternating: alternating.dup.valid_encoding?
coderange_ascii: ascii.dup.valid_encoding?
+32 -42
View File
@@ -713,6 +713,10 @@ search_nonascii(const char *p, const char *e)
{
const char *s, *t;
if (p < e && !ISASCII(*p)) {
return p;
}
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# if SIZEOF_UINTPTR_T == 8
# define NONASCII_MASK UINT64_C(0x8080808080808080)
@@ -2297,26 +2301,22 @@ enc_strlen(const char *p, const char *e, rb_encoding *enc, int cr)
c = 0;
if (ENC_CODERANGE_CLEAN_P(cr)) {
while (p < e) {
if (ISASCII(*p)) {
q = search_nonascii(p, e);
if (!q)
return c + (e - p);
c += q - p;
p = q;
}
q = search_nonascii(p, e);
if (!q)
return c + (e - p);
c += q - p;
p = q;
p += rb_enc_fast_mbclen(p, e, enc);
c++;
}
}
else {
while (p < e) {
if (ISASCII(*p)) {
q = search_nonascii(p, e);
if (!q)
return c + (e - p);
c += q - p;
p = q;
}
q = search_nonascii(p, e);
if (!q)
return c + (e - p);
c += q - p;
p = q;
p += rb_enc_mbclen(p, e, enc);
c++;
}
@@ -2354,15 +2354,13 @@ rb_enc_strlen_cr(const char *p, const char *e, rb_encoding *enc, int *cr)
else if (rb_enc_asciicompat(enc)) {
c = 0;
while (p < e) {
if (ISASCII(*p)) {
q = search_nonascii(p, e);
if (!q) {
if (!*cr) *cr = ENC_CODERANGE_7BIT;
return c + (e - p);
}
c += q - p;
p = q;
q = search_nonascii(p, e);
if (!q) {
if (!*cr) *cr = ENC_CODERANGE_7BIT;
return c + (e - p);
}
c += q - p;
p = q;
ret = rb_enc_precise_mbclen(p, e, enc);
if (MBCLEN_CHARFOUND_P(ret)) {
*cr |= ENC_CODERANGE_VALID;
@@ -3020,16 +3018,14 @@ str_nth_len(const char *p, const char *e, long *nthp, rb_encoding *enc)
*nthp = nth;
return (char *)e;
}
if (ISASCII(*p)) {
p2 = search_nonascii(p, e2);
if (!p2) {
nth -= e2 - p;
*nthp = nth;
return (char *)e2;
}
nth -= p2 - p;
p = p2;
p2 = search_nonascii(p, e2);
if (!p2) {
nth -= e2 - p;
*nthp = nth;
return (char *)e2;
}
nth -= p2 - p;
p = p2;
n = rb_enc_mbclen(p, e, enc);
p += n;
nth--;
@@ -11850,17 +11846,11 @@ enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl, int cr)
else if (MBCLEN_CHARFOUND_P(ret)) {
cr = ENC_CODERANGE_VALID;
p += MBCLEN_CHARFOUND_LEN(ret);
/*
* After a valid multibyte character, skip the following ASCII run.
* If the next byte is already non-ASCII, search_nonascii would only
* rediscover p after its word-at-a-time setup.
*/
if (p < e && ISASCII(*p)) {
p = search_nonascii(p, e);
if (!p) {
p = e;
break;
}
/* After a multibyte character, fast-skip the following ASCII run. */
p = search_nonascii(p, e);
if (!p) {
p = e;
break;
}
}
else if (MBCLEN_INVALID_P(ret)) {