Merge branch 'str-is-ascii-ifunc' into 'main'

gutf8: Add ifunc resolver for g_str_is_ascii() too

Closes #3511

See merge request GNOME/glib!4364
This commit is contained in:
Philip Withnall 2024-10-22 17:37:32 +00:00
commit 4c3f06acbf

View File

@ -42,6 +42,10 @@
#include "glibintl.h" #include "glibintl.h"
#include "gvalgrind.h" #include "gvalgrind.h"
#if g_macro__has_attribute(ifunc) && !defined(G_OS_WIN32)
#define HAVE_WORKING_IFUNC_ATTRIBUTE 1
#endif
#define UTF8_COMPUTE(Char, Mask, Len) \ #define UTF8_COMPUTE(Char, Mask, Len) \
if (Char < 128) \ if (Char < 128) \
{ \ { \
@ -1841,7 +1845,7 @@ g_utf8_validate_native (const char *str,
return *str == 0; return *str == 0;
} }
#if g_macro__has_attribute(ifunc) && !defined(G_OS_WIN32) #ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
/* The fast implementation of UTF-8 validation in `utf8_verify()` technically /* The fast implementation of UTF-8 validation in `utf8_verify()` technically
* uses undefined behaviour when the string length is not provided (i.e. when * uses undefined behaviour when the string length is not provided (i.e. when
* its looking for a trailing nul terminator): when doing word-sized reads of * its looking for a trailing nul terminator): when doing word-sized reads of
@ -1882,14 +1886,19 @@ g_utf8_validate_valgrind (const char *str,
return g_utf8_validate_len (str, max_len, end); return g_utf8_validate_len (str, max_len, end);
} }
static gboolean (*resolve_g_utf8_validate (void)) (const char *, gssize, const char **) typedef gboolean (*GUtf8ValidateFunc) (const char *str,
gssize max_len,
const char **end);
static GUtf8ValidateFunc
resolve_g_utf8_validate (void)
{ {
if (RUNNING_ON_VALGRIND) if (RUNNING_ON_VALGRIND)
return g_utf8_validate_valgrind; return g_utf8_validate_valgrind;
else else
return g_utf8_validate_native; return g_utf8_validate_native;
} }
#endif #endif /* HAVE_WORKING_IFUNC_ATTRIBUTE */
/** /**
* g_utf8_validate: * g_utf8_validate:
@ -1924,7 +1933,7 @@ gboolean
g_utf8_validate (const char *str, g_utf8_validate (const char *str,
gssize max_len, gssize max_len,
const gchar **end) const gchar **end)
#if g_macro__has_attribute(ifunc) && !defined(G_OS_WIN32) #ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
__attribute__((ifunc ("resolve_g_utf8_validate"))); __attribute__((ifunc ("resolve_g_utf8_validate")));
#else #else
{ {
@ -1960,6 +1969,38 @@ g_utf8_validate_len (const char *str,
return max_len == 0; return max_len == 0;
} }
static gboolean
g_str_is_ascii_native (const char *str)
{
utf8_verify_ascii (&str, NULL);
return *str == 0;
}
#ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
/* See above comment about `ifunc` use for g_utf8_validate(). */
static gboolean
g_str_is_ascii_valgrind (const char *str)
{
size_t len = strlen (str);
utf8_verify_ascii (&str, &len);
return *str == 0;
}
typedef gboolean (*GStrIsAsciiFunc) (const char *str);
static GStrIsAsciiFunc
resolve_g_str_is_ascii (void)
{
if (RUNNING_ON_VALGRIND)
return g_str_is_ascii_valgrind;
else
return g_str_is_ascii_native;
}
#endif /* HAVE_WORKING_IFUNC_ATTRIBUTE */
/** /**
* g_str_is_ascii: * g_str_is_ascii:
* @str: a string * @str: a string
@ -1971,13 +2012,18 @@ g_utf8_validate_len (const char *str,
* *
* Since: 2.40 * Since: 2.40
*/ */
#if g_macro__has_attribute(no_sanitize_address)
__attribute__((no_sanitize_address))
#endif
gboolean gboolean
g_str_is_ascii (const gchar *str) g_str_is_ascii (const gchar *str)
#ifdef HAVE_WORKING_IFUNC_ATTRIBUTE
__attribute__((ifunc ("resolve_g_str_is_ascii")));
#else
{ {
utf8_verify_ascii (&str, NULL); return g_str_is_ascii_native (str);
return *str == 0;
} }
#endif
/** /**
* g_unichar_validate: * g_unichar_validate: