diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2025-08-24 22:53:21 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2025-08-27 11:46:25 +0200 |
| commit | 8e478e06c2c09e8d74fcaa6cca84f7db14d23265 (patch) | |
| tree | c1913a33402c9b63f6cbc1288d05d1ef4c48bb7c /src/json.c | |
| parent | dd2c70e878e4bc7fcf26f33523a45f0d854a29e4 (diff) | |
improved testing & src cleanup
Diffstat (limited to 'src/json.c')
| -rw-r--r-- | src/json.c | 23 |
1 files changed, 15 insertions, 8 deletions
@@ -186,22 +186,29 @@ parse_result parse_string(byte *src, uptr start_pos, uptr max_pos) { result.pos = start_pos + 1; // SIMD optimization: process 32 bytes at a time using AVX2 - bytex32 quote_mask = _mm256_set1_epi8('"'); + bytex32 quote_bytes = _mm256_set1_epi8('"'); for (; result.pos + 32 <= max_pos; result.pos += 32) { bytex32 chunk = _mm256_loadu_si256((bytex32 *)(src + result.pos)); - bytex32 cmp = _mm256_cmpeq_epi8(chunk, quote_mask); - i32 mask = _mm256_movemask_epi8(cmp); + i32 quote_mask = + _mm256_movemask_epi8(_mm256_cmpeq_epi8(chunk, quote_bytes)); - if (mask != 0) { - result.pos += stdc_trailing_zeros_ui(mask); - if (src[result.pos - 1] != '\\') break; + if (quote_mask != 0) { + result.pos += stdc_trailing_zeros_ui(quote_mask); + break; }; } // Fall back to original byte-by-byte processing for the remaining bytes - while (src[result.pos] != '"' && src[result.pos - 1] != '\\') { - result.pos++; + for (; result.pos < max_pos; result.pos++) { + if (src[result.pos] == '"') { + uptr backslash_count = 0; + while (backslash_count < result.pos && + src[result.pos - backslash_count - 1] == '\\') { + backslash_count++; + } + if (!(backslash_count & 1)) break; + } } assert_parse(src[result.pos] == '"', "invalid string end", src, result.pos); |
