Skip to content

Commit 2c3850e

Browse files
committed
Reuse fast funcs.
1 parent db7aacf commit 2c3850e

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

sqlite3/libc/string.h

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void *memmove(void *dest, const void *src, size_t n) {
3838

3939
#ifdef __wasm_simd128__
4040

41-
// SIMD versions of some string.h functions.
41+
// SIMD implementations of string.h functions.
4242

4343
__attribute__((weak))
4444
int memcmp(const void *v1, const void *v2, size_t n) {
@@ -220,7 +220,7 @@ static int __strcmp_s(const char *s1, const char *s2) {
220220
__attribute__((weak, always_inline))
221221
int strcmp(const char *s1, const char *s2) {
222222
// Skip the vector search when comparing against small literal strings.
223-
if (__builtin_constant_p(strlen(s2) && strlen(s2) < sizeof(v128_t))) {
223+
if (__builtin_constant_p(strlen(s2)) && strlen(s2) < sizeof(v128_t)) {
224224
return __strcmp_s(s1, s2);
225225
}
226226
return __strcmp(s1, s2);
@@ -317,6 +317,9 @@ char *strrchr(const char *s, int c) {
317317
if (__builtin_constant_p(c) && (char)c == 0) {
318318
return (char *)s + strlen(s);
319319
}
320+
// This could also be implemented in a single pass using strchr,
321+
// advancing to the next match until no more matches are found.
322+
// That would be suboptimal with lots of consecutive matches.
320323
return (char *)memrchr(s, c, strlen(s) + 1);
321324
}
322325

@@ -416,10 +419,67 @@ size_t strcspn(const char *s, const char *c) {
416419
return s - a;
417420
}
418421

422+
// Given the above SIMD implementations,
423+
// these are best implemented as
424+
// small wrappers over those functions.
425+
426+
// Simple wrappers from musl:
427+
// - mempcpy
428+
// - strcat
429+
// - strdup
430+
// - strndup
431+
// - strnlen
432+
// - strpbrk
433+
// - strsep
434+
// - strtok
435+
436+
__attribute__((weak, always_inline))
437+
void *memccpy(void *__restrict dest, const void *__restrict src, int c, size_t n) {
438+
const void *m = memchr(src, c, n);
439+
if (m != NULL) {
440+
n = (char *)m - (char *)src + 1;
441+
m = (char *)dest + n;
442+
}
443+
memcpy(dest, src, n);
444+
return (void *)m;
445+
}
446+
447+
__attribute__((weak, always_inline))
448+
char *stpcpy(char *__restrict dest, const char *__restrict src) {
449+
size_t slen = strlen(src);
450+
memcpy(dest, src, slen + 1);
451+
return dest + slen;
452+
}
453+
454+
__attribute__((weak, always_inline))
455+
char *stpncpy(char *__restrict dest, const char *__restrict src, size_t n) {
456+
size_t strnlen(const char *s, size_t n);
457+
size_t slen = strnlen(src, n);
458+
memcpy(dest, src, slen);
459+
memset(dest + slen, 0, n - slen);
460+
return dest + slen;
461+
}
462+
463+
__attribute__((weak, always_inline))
464+
char *strcpy(char *__restrict dest, const char *__restrict src) {
465+
stpcpy(dest, src);
466+
return dest;
467+
}
468+
469+
__attribute__((weak, always_inline))
470+
char *strncpy(char *__restrict dest, const char *__restrict src, size_t n) {
471+
stpncpy(dest, src, n);
472+
return dest;
473+
}
474+
419475
__attribute__((weak, always_inline))
420-
char *strpbrk(const char *s, const char *b) {
421-
s += strcspn(s, b);
422-
return *s ? (char *)s : 0;
476+
char *strncat(char *__restrict dest, const char *__restrict src, size_t n) {
477+
size_t strnlen(const char *s, size_t n);
478+
size_t dlen = strlen(dest);
479+
size_t slen = strnlen(src, n);
480+
memcpy(dest + dlen, src, slen);
481+
dest[dlen + slen] = 0;
482+
return dest;
423483
}
424484

425485
#endif // __wasm_simd128__

0 commit comments

Comments
 (0)