diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index 1879594651..296d0cf25d 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -41,6 +41,9 @@ #include "vm/NativeObject-inl.h" +#include "mozilla-config.h" +#include "plvmx.h" + using namespace js; using mozilla::IsFinite; @@ -452,7 +455,7 @@ intl_availableLocales(JSContext* cx, CountAvailable countAvailable, if (!lang) return false; char* p; - while ((p = strchr(lang, '_'))) + while ((p = VMX_STRCHR(lang, '_'))) *p = '-'; RootedAtom a(cx, Atomize(cx, lang, strlen(lang))); if (!a) diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 1df251898c..7cd08dfd23 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -4722,11 +4722,25 @@ js_strchr_limit(const CharT* s, char16_t c, const CharT* limit) return nullptr; } +template const char16_t* +js_strchr_limit(const char16_t* s, char16_t c, const char16_t* limit); + +#ifdef TENFOURFOX_VMX +#warning using VMX latin-1 js_strchr_limit + +template <> const Latin1Char * +js_strchr_limit(const Latin1Char* s, char16_t c, const Latin1Char* limit) +{ + return (const Latin1Char *)VMX_MEMCHR((const void *)s, c, + (1 + (uint32_t)limit - (uint32_t)s)); +} + +#else +#warning using template latin-1 js_strchr_limit template const Latin1Char* js_strchr_limit(const Latin1Char* s, char16_t c, const Latin1Char* limit); +#endif -template const char16_t* -js_strchr_limit(const char16_t* s, char16_t c, const char16_t* limit); char16_t* js::InflateString(ExclusiveContext* cx, const char* bytes, size_t* lengthp) diff --git a/nsprpub/lib/libc/include/plvmx.h b/nsprpub/lib/libc/include/plvmx.h index b4a651c8a2..4c9903b0f2 100644 --- a/nsprpub/lib/libc/include/plvmx.h +++ b/nsprpub/lib/libc/include/plvmx.h @@ -15,6 +15,7 @@ extern "C" { int vmx_haschr(const void *b, int c, size_t len); void *vmx_memchr(const void *b, int c, size_t len); +char *vmx_strchr(const char *p, int ch); #if defined (__cplusplus) } @@ -22,6 +23,7 @@ void *vmx_memchr(const void *b, int c, size_t len); #define VMX_HASCHR vmx_haschr #define VMX_MEMCHR vmx_memchr +#define VMX_STRCHR vmx_strchr #else #if defined (__cplusplus) #define VMX_HASCHR(a,b,c) (memchr(a,b,c) != nullptr) @@ -29,6 +31,7 @@ void *vmx_memchr(const void *b, int c, size_t len); #define VMX_HASCHR(a,b,c) (!!memchr(a,b,c)) #endif #define VMX_MEMCHR memchr +#define VMX_STRCHR strchr #endif #endif diff --git a/nsprpub/lib/libc/src/plvmx.c b/nsprpub/lib/libc/src/plvmx.c index dd80351b3b..4018d74a8c 100644 --- a/nsprpub/lib/libc/src/plvmx.c +++ b/nsprpub/lib/libc/src/plvmx.c @@ -117,3 +117,58 @@ void *vmx_memchr(const void *b, int c, size_t length) { fprintf(stderr, "failed vmx_memchr()\n"); return NULL; } + +char *vmx_strchr(const char *p, int ch) { + unsigned char c = (unsigned char)ch; + unsigned int val; + if ((uint32_t)p & 15) { + for (;((uint32_t)p & 15);++p) { + if (*p == c) return ((char *)p); + if (*p == '\0') return NULL; + } + } + + unsigned int mashedByte = (c << 24) | + (c << 16) | + (c << 8) | c; + const vector unsigned char searchVector = (vector unsigned int){ + mashedByte, mashedByte, mashedByte, mashedByte}; + const vector unsigned char nullVector = vec_splat_u8(0); + + for(; ; p+=16) { + const vector unsigned char *w = (const vector unsigned char*)p; + if (vec_any_eq(*w, searchVector)) break; + if (vec_any_eq(*w, nullVector)) return NULL; + } + + // Some byte has the result; look in groups of 4 to find which one. + // Unroll the loop. + val = *(unsigned int*)p; + if (((val >> 24) & 0xFF) == c) return (void *)p; + if (((val >> 16) & 0xFF) == c) return (void *)(1 + p); + if (((val >> 8) & 0xFF) == c) return (void *)(2 + p); + if ((val & 0xFF) == c) return (void *)(3 + p); + p += 4; + val = *(unsigned int*)p; + if (((val >> 24) & 0xFF) == c) return (void *)p; + if (((val >> 16) & 0xFF) == c) return (void *)(1 + p); + if (((val >> 8) & 0xFF) == c) return (void *)(2 + p); + if ((val & 0xFF) == c) return (void *)(3 + p); + p += 4; + val = *(unsigned int*)p; + if (((val >> 24) & 0xFF) == c) return (void *)p; + if (((val >> 16) & 0xFF) == c) return (void *)(1 + p); + if (((val >> 8) & 0xFF) == c) return (void *)(2 + p); + if ((val & 0xFF) == c) return (void *)(3 + p); + p += 4; + val = *(unsigned int*)p; + if (((val >> 24) & 0xFF) == c) return (void *)p; + if (((val >> 16) & 0xFF) == c) return (void *)(1 + p); + if (((val >> 8) & 0xFF) == c) return (void *)(2 + p); + if ((val & 0xFF) == c) return (void *)(3 + p); + + // unreachable + fprintf(stderr, "failed vmx_strchr()\n"); + return NULL; +} +