Skip to content

Commit

Permalink
- json: bad simd detection
Browse files Browse the repository at this point in the history
  • Loading branch information
oknenavin committed Jul 5, 2024
1 parent 5a4ea9f commit 1f8eca0
Showing 1 changed file with 44 additions and 38 deletions.
82 changes: 44 additions & 38 deletions src/cxon/lang/common/cio/char.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,11 @@ namespace cxon { namespace cio { namespace chr {
default : return poke<X>(o, c, cx);
}
}
template <typename Y = X>
static constexpr bool use_simd_() { return CXON_USE_SIMD && !Y::produce_strict_javascript; }
template <typename O, typename Cx, typename Y = X>
static auto range(O& o, const char* f, const char* l, Cx& cx)
-> enable_if_t<( is_unquoted_key_context<X>::value || !Y::assume_no_escapes) && (!CXON_USE_SIMD || Y::produce_strict_javascript), bool>
-> enable_if_t<( is_unquoted_key_context<X>::value || !Y::assume_no_escapes) && !use_simd_<Y>(), bool>
{
char const* a = f;
for ( ; f != l; ++f) {
Expand Down Expand Up @@ -492,50 +494,54 @@ namespace cxon { namespace cio { namespace chr {
}
template <typename O, typename Cx, typename Y = X>
static auto range(O& o, const char* f, const char* l, Cx& cx)
-> enable_if_t<( is_unquoted_key_context<X>::value || !Y::assume_no_escapes) && ( CXON_USE_SIMD && !Y::produce_strict_javascript), bool>
-> enable_if_t<( is_unquoted_key_context<X>::value || !Y::assume_no_escapes) && use_simd_<Y>(), bool>
{
char const *a = f;

__m128i const v1 = _mm_set1_epi8('"');
__m128i const v2 = _mm_set1_epi8('\\');
__m128i const v3 = _mm_set1_epi8(0x1F);
std::size_t n = l - f;
while (n >= 16) {
__m128i r0 = _mm_loadu_si128((__m128i const*)f);
__m128i r1 = _mm_cmpeq_epi8(r0, v1);
__m128i r2 = _mm_cmpeq_epi8(r0, v2);
__m128i r3 = _mm_cmpeq_epi8(_mm_min_epu8(r0, v3), r0);
__m128i r4 = _mm_or_si128(_mm_or_si128(r1, r2), r3);
if (int r = _mm_movemask_epi8(r4)) {
int e = ffs(r);
if (a != (f += e) && !poke<Y>(o, a, f, cx)) return false;
a = f;
for (auto* k = f + 16 - e; f != k; ++f, ++e) {
if ((1 << e) & r) {
if (a != f && !poke<Y>(o, a, f, cx)) return false;
if (!value(o, *f, cx)) return false;
a = f + 1;
# if CXON_USE_SIMD
char const *a = f;

__m128i const v1 = _mm_set1_epi8('"');
__m128i const v2 = _mm_set1_epi8('\\');
__m128i const v3 = _mm_set1_epi8(0x1F);
std::size_t n = l - f;
while (n >= 16) {
__m128i r0 = _mm_loadu_si128((__m128i const*)f);
__m128i r1 = _mm_cmpeq_epi8(r0, v1);
__m128i r2 = _mm_cmpeq_epi8(r0, v2);
__m128i r3 = _mm_cmpeq_epi8(_mm_min_epu8(r0, v3), r0);
__m128i r4 = _mm_or_si128(_mm_or_si128(r1, r2), r3);
if (int r = _mm_movemask_epi8(r4)) {
int e = ffs(r);
if (a != (f += e) && !poke<Y>(o, a, f, cx)) return false;
a = f;
for (auto* k = f + 16 - e; f != k; ++f, ++e) {
if ((1 << e) & r) {
if (a != f && !poke<Y>(o, a, f, cx)) return false;
if (!value(o, *f, cx)) return false;
a = f + 1;
}
}
if (a != f && !poke<Y>(o, a, f, cx)) return false;
a = f, f -= 16;
}
if (a != f && !poke<Y>(o, a, f, cx)) return false;
a = f, f -= 16;
f += 16, n -= 16;
}
if (a != f) {
if (!poke<Y>(o, a, f, cx)) return false;
a = f;
}
f += 16, n -= 16;
}
if (a != f) {
if (!poke<Y>(o, a, f, cx)) return false;
a = f;
}

for ( ; f != l; ++f) {
if (should_escape_<Y>(*f)) {
if (a != f && !poke<Y>(o, a, f, cx)) return false;
if (!value(o, *f, cx)) return false;
a = f + 1;
for ( ; f != l; ++f) {
if (should_escape_<Y>(*f)) {
if (a != f && !poke<Y>(o, a, f, cx)) return false;
if (!value(o, *f, cx)) return false;
a = f + 1;
}
}
}

return a == f || poke<Y>(o, a, f, cx);
return a == f || poke<Y>(o, a, f, cx);
# else
return cx/X::read_error::unexpected;
# endif
}
template <typename O, typename Cx, typename Y = X>
static auto range(O& o, const char* f, const char* l, Cx& cx)
Expand Down

0 comments on commit 1f8eca0

Please sign in to comment.