Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 14bd2c1

Browse files
enh-googleGerrit Code Review
authored andcommitted
Merge "<wctype.h>: de-pessimize the isw*() functions." into main
2 parents d1d4e8b + 8f07d34 commit 14bd2c1

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed

libc/bionic/icu_wrappers.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,3 @@ int32_t __icu_getIntPropertyValue(wint_t wc, UProperty property) {
4040
reinterpret_cast<u_getIntPropertyValue_t>(__find_icu_symbol("u_getIntPropertyValue"));
4141
return u_getIntPropertyValue ? u_getIntPropertyValue(wc, property) : 0;
4242
}
43-
44-
bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int)) {
45-
typedef UBool (*u_hasBinaryProperty_t)(UChar32, UProperty);
46-
static auto u_hasBinaryProperty =
47-
reinterpret_cast<u_hasBinaryProperty_t>(__find_icu_symbol("u_hasBinaryProperty"));
48-
return u_hasBinaryProperty ? u_hasBinaryProperty(wc, property) : fallback(wc);
49-
}

libc/bionic/wctype.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,40 +54,57 @@ enum {
5454
WC_TYPE_MAX
5555
};
5656

57-
int iswalnum(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_ALNUM, isalnum); }
57+
static u_hasBinaryProperty_t __find_u_hasBinaryProperty() {
58+
static auto u_hasBinaryProperty =
59+
reinterpret_cast<u_hasBinaryProperty_t>(__find_icu_symbol("u_hasBinaryProperty"));
60+
return u_hasBinaryProperty;
61+
}
62+
63+
#define DO_ISW(icu_constant, narrow_fn) \
64+
u_hasBinaryProperty_t u_hasBinaryProperty; \
65+
if (__predict_true(wc < 0x80) || \
66+
!(u_hasBinaryProperty = __find_u_hasBinaryProperty())) { \
67+
return narrow_fn(wc); \
68+
} \
69+
return u_hasBinaryProperty(wc, icu_constant); \
70+
71+
int iswalnum(wint_t wc) { DO_ISW(UCHAR_POSIX_ALNUM, isalnum); }
5872
__strong_alias(iswalnum_l, iswalnum);
59-
int iswalpha(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_ALPHABETIC, isalpha); }
73+
int iswalpha(wint_t wc) { DO_ISW(UCHAR_ALPHABETIC, isalpha); }
6074
__strong_alias(iswalpha_l, iswalpha);
61-
int iswblank(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_BLANK, isblank); }
75+
int iswblank(wint_t wc) { DO_ISW(UCHAR_POSIX_BLANK, isblank); }
6276
__strong_alias(iswblank_l, iswblank);
63-
int iswgraph(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_GRAPH, isgraph); }
77+
int iswgraph(wint_t wc) { DO_ISW(UCHAR_POSIX_GRAPH, isgraph); }
6478
__strong_alias(iswgraph_l, iswgraph);
65-
int iswlower(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_LOWERCASE, islower); }
79+
int iswlower(wint_t wc) { DO_ISW(UCHAR_LOWERCASE, islower); }
6680
__strong_alias(iswlower_l, iswlower);
67-
int iswprint(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_PRINT, isprint); }
81+
int iswprint(wint_t wc) { DO_ISW(UCHAR_POSIX_PRINT, isprint); }
6882
__strong_alias(iswprint_l, iswprint);
69-
int iswspace(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_WHITE_SPACE, isspace); }
83+
int iswspace(wint_t wc) { DO_ISW(UCHAR_WHITE_SPACE, isspace); }
7084
__strong_alias(iswspace_l, iswspace);
71-
int iswupper(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_UPPERCASE, isupper); }
85+
int iswupper(wint_t wc) { DO_ISW(UCHAR_UPPERCASE, isupper); }
7286
__strong_alias(iswupper_l, iswupper);
73-
int iswxdigit(wint_t wc) { return __icu_hasBinaryProperty(wc, UCHAR_POSIX_XDIGIT, isxdigit); }
87+
int iswxdigit(wint_t wc) { DO_ISW(UCHAR_POSIX_XDIGIT, isxdigit); }
7488
__strong_alias(iswxdigit_l, iswxdigit);
7589

7690
int iswcntrl(wint_t wc) {
91+
if (wc < 0x80) return iscntrl(wc);
7792
typedef int8_t (*FnT)(UChar32);
7893
static auto u_charType = reinterpret_cast<FnT>(__find_icu_symbol("u_charType"));
7994
return u_charType ? (u_charType(wc) == U_CONTROL_CHAR) : iscntrl(wc);
8095
}
8196
__strong_alias(iswcntrl_l, iswcntrl);
8297

8398
int iswdigit(wint_t wc) {
99+
if (wc < 0x80) return isdigit(wc);
84100
typedef UBool (*FnT)(UChar32);
85101
static auto u_isdigit = reinterpret_cast<FnT>(__find_icu_symbol("u_isdigit"));
86102
return u_isdigit ? u_isdigit(wc) : isdigit(wc);
87103
}
88104
__strong_alias(iswdigit_l, iswdigit);
89105

90106
int iswpunct(wint_t wc) {
107+
if (wc < 0x80) return ispunct(wc);
91108
typedef UBool (*FnT)(UChar32);
92109
static auto u_ispunct = reinterpret_cast<FnT>(__find_icu_symbol("u_ispunct"));
93110
return u_ispunct ? u_ispunct(wc) : ispunct(wc);

libc/bionic/wcwidth.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ int wcwidth(wchar_t wc) {
7373

7474
// Hangeul choseong filler U+115F is default ignorable, so we check default
7575
// ignorability only after we've already handled Hangeul jamo above.
76-
if (__icu_hasBinaryProperty(wc, UCHAR_DEFAULT_IGNORABLE_CODE_POINT, nullptr)) return 0;
76+
static auto u_hasBinaryProperty =
77+
reinterpret_cast<u_hasBinaryProperty_t>(__find_icu_symbol("u_hasBinaryProperty"));
78+
if (u_hasBinaryProperty && u_hasBinaryProperty(wc, UCHAR_DEFAULT_IGNORABLE_CODE_POINT)) return 0;
7779

7880
// A few weird special cases where EastAsianWidth is not helpful for us.
7981
if (wc >= 0x3248 && wc <= 0x4dff) {

libc/private/icu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ enum UHangulSyllableType {
8080

8181
int8_t __icu_charType(wint_t wc);
8282
int32_t __icu_getIntPropertyValue(wint_t wc, UProperty property);
83-
bool __icu_hasBinaryProperty(wint_t wc, UProperty property, int (*fallback)(int));
83+
84+
typedef UBool (*u_hasBinaryProperty_t)(UChar32, UProperty);
8485

8586
void* __find_icu_symbol(const char* symbol_name);
8687

0 commit comments

Comments
 (0)