summaryrefslogtreecommitdiff
path: root/src/common/utf8.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-11 23:27:41 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-11 23:27:41 +0300
commit472ed3e4e50a165638acecaf071ec3c2c13c451f (patch)
treed1894debde800d8e87d3c242ae6c3f4760c68787 /src/common/utf8.c
parent8d9f7c7cb39359d62bf28ef1775b944a7dddd6fb (diff)
core: optimize struct layouts, eliminate branches, and fix event loop dispatch
- Fix Wayland event loop lockout by properly decoupling read arming and adding poll-backed dispatching - Support standalone display lifecycle without requiring caller to manage a loop - Eliminate alignment holes across yasl_surface, yasl_display, seat, touch_point, and conn_drag using pahole - Replace branching state/button decoders with compile-time locked LUTs and branchless bitwise operations - Accelerate UTF-8 validation with 64-bit word scanning for ASCII runs
Diffstat (limited to 'src/common/utf8.c')
-rw-r--r--src/common/utf8.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/common/utf8.c b/src/common/utf8.c
index 089fd89..7f2e6f1 100644
--- a/src/common/utf8.c
+++ b/src/common/utf8.c
@@ -3,30 +3,46 @@
#include <stdbool.h>
#include <stdint.h>
+#ifndef likely
+#define likely(x) __builtin_expect(!!(x), 1)
+#endif
+#ifndef unlikely
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+
bool yasl_utf8_validate(const char *str, size_t len)
{
const unsigned char *p = (const unsigned char *)str;
const unsigned char *end = p + len;
while (p < end) {
- if (*p < 0x80) {
+ while (p + 8 <= end) {
+ uint64_t v;
+ memcpy(&v, p, 8);
+ if (v & 0x8080808080808080ull)
+ break;
+ p += 8;
+ }
+ if (p >= end) break;
+
+ if (likely(*p < 0x80)) {
p++;
} else if ((*p & 0xe0) == 0xc0) {
- if (p + 1 >= end || (p[1] & 0xc0) != 0x80 || (*p & 0x1e) == 0)
+ if (unlikely(p + 1 >= end || (p[1] & 0xc0) != 0x80 || (*p & 0x1e) == 0))
return false;
p += 2;
} else if ((*p & 0xf0) == 0xe0) {
- if (p + 2 >= end || (p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80)
+ if (unlikely(p + 2 >= end || (p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80))
return false;
uint32_t cp = ((p[0] & 0x0f) << 12) | ((p[1] & 0x3f) << 6) | (p[2] & 0x3f);
- if (cp < 0x800 || (cp >= 0xd800 && cp <= 0xdfff))
+ if (unlikely(cp < 0x800 || (cp >= 0xd800 && cp <= 0xdfff)))
return false;
p += 3;
} else if ((*p & 0xf8) == 0xf0) {
- if (p + 3 >= end || (p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80)
+ if (unlikely(p + 3 >= end || (p[1] & 0xc0) != 0x80 || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80))
return false;
uint32_t cp = ((p[0] & 0x07) << 18) | ((p[1] & 0x3f) << 12) | ((p[2] & 0x3f) << 6) | (p[3] & 0x3f);
- if (cp < 0x10000 || cp > 0x10ffff)
+ if (unlikely(cp < 0x10000 || cp > 0x10ffff))
return false;
p += 4;
} else {