|
1 |
| -/* auto-generated on 2025-06-30 19:51:09 -0400. Do not edit! */ |
| 1 | +/* auto-generated on 2025-07-16 22:15:14 -0400. Do not edit! */ |
2 | 2 | /* begin file src/ada.cpp */
|
3 | 3 | #include "ada.h"
|
4 | 4 | /* begin file src/checkers.cpp */
|
@@ -67,7 +67,8 @@ static constexpr std::array<uint8_t, 256> path_signature_table =
|
67 | 67 | std::array<uint8_t, 256> result{};
|
68 | 68 | for (size_t i = 0; i < 256; i++) {
|
69 | 69 | if (i <= 0x20 || i == 0x22 || i == 0x23 || i == 0x3c || i == 0x3e ||
|
70 |
| - i == 0x3f || i == 0x60 || i == 0x7b || i == 0x7d || i > 0x7e) { |
| 70 | + i == 0x3f || i == 0x5e || i == 0x60 || i == 0x7b || i == 0x7d || |
| 71 | + i > 0x7e) { |
71 | 72 | result[i] = 1;
|
72 | 73 | } else if (i == 0x25) {
|
73 | 74 | result[i] = 8;
|
@@ -10444,6 +10445,8 @@ ADA_POP_DISABLE_WARNINGS
|
10444 | 10445 | #include <arm_neon.h>
|
10445 | 10446 | #elif ADA_SSE2
|
10446 | 10447 | #include <emmintrin.h>
|
| 10448 | +#elif ADA_LSX |
| 10449 | +#include <lsxintrin.h> |
10447 | 10450 | #endif
|
10448 | 10451 |
|
10449 | 10452 | #include <ranges>
|
@@ -10552,6 +10555,38 @@ ada_really_inline bool has_tabs_or_newline(
|
10552 | 10555 | }
|
10553 | 10556 | return _mm_movemask_epi8(running) != 0;
|
10554 | 10557 | }
|
| 10558 | +#elif ADA_LSX |
| 10559 | +ada_really_inline bool has_tabs_or_newline( |
| 10560 | + std::string_view user_input) noexcept { |
| 10561 | + // first check for short strings in which case we do it naively. |
| 10562 | + if (user_input.size() < 16) { // slow path |
| 10563 | + return std::ranges::any_of(user_input, is_tabs_or_newline); |
| 10564 | + } |
| 10565 | + // fast path for long strings (expected to be common) |
| 10566 | + size_t i = 0; |
| 10567 | + const __m128i mask1 = __lsx_vrepli_b('\r'); |
| 10568 | + const __m128i mask2 = __lsx_vrepli_b('\n'); |
| 10569 | + const __m128i mask3 = __lsx_vrepli_b('\t'); |
| 10570 | + // If we supported SSSE3, we could use the algorithm that we use for NEON. |
| 10571 | + __m128i running{0}; |
| 10572 | + for (; i + 15 < user_input.size(); i += 16) { |
| 10573 | + __m128i word = __lsx_vld((const __m128i*)(user_input.data() + i), 0); |
| 10574 | + running = __lsx_vor_v( |
| 10575 | + __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1), |
| 10576 | + __lsx_vseq_b(word, mask2))), |
| 10577 | + __lsx_vseq_b(word, mask3)); |
| 10578 | + } |
| 10579 | + if (i < user_input.size()) { |
| 10580 | + __m128i word = __lsx_vld( |
| 10581 | + (const __m128i*)(user_input.data() + user_input.length() - 16), 0); |
| 10582 | + running = __lsx_vor_v( |
| 10583 | + __lsx_vor_v(running, __lsx_vor_v(__lsx_vseq_b(word, mask1), |
| 10584 | + __lsx_vseq_b(word, mask2))), |
| 10585 | + __lsx_vseq_b(word, mask3)); |
| 10586 | + } |
| 10587 | + if (__lsx_bz_v(running)) return false; |
| 10588 | + return true; |
| 10589 | +} |
10555 | 10590 | #else
|
10556 | 10591 | ada_really_inline bool has_tabs_or_newline(
|
10557 | 10592 | std::string_view user_input) noexcept {
|
@@ -11385,6 +11420,58 @@ ada_really_inline size_t find_next_host_delimiter_special(
|
11385 | 11420 | }
|
11386 | 11421 | return size_t(view.length());
|
11387 | 11422 | }
|
| 11423 | +#elif ADA_LSX |
| 11424 | +ada_really_inline size_t find_next_host_delimiter_special( |
| 11425 | + std::string_view view, size_t location) noexcept { |
| 11426 | + // first check for short strings in which case we do it naively. |
| 11427 | + if (view.size() - location < 16) { // slow path |
| 11428 | + for (size_t i = location; i < view.size(); i++) { |
| 11429 | + if (view[i] == ':' || view[i] == '/' || view[i] == '\\' || |
| 11430 | + view[i] == '?' || view[i] == '[') { |
| 11431 | + return i; |
| 11432 | + } |
| 11433 | + } |
| 11434 | + return size_t(view.size()); |
| 11435 | + } |
| 11436 | + // fast path for long strings (expected to be common) |
| 11437 | + size_t i = location; |
| 11438 | + const __m128i mask1 = __lsx_vrepli_b(':'); |
| 11439 | + const __m128i mask2 = __lsx_vrepli_b('/'); |
| 11440 | + const __m128i mask3 = __lsx_vrepli_b('\\'); |
| 11441 | + const __m128i mask4 = __lsx_vrepli_b('?'); |
| 11442 | + const __m128i mask5 = __lsx_vrepli_b('['); |
| 11443 | + |
| 11444 | + for (; i + 15 < view.size(); i += 16) { |
| 11445 | + __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0); |
| 11446 | + __m128i m1 = __lsx_vseq_b(word, mask1); |
| 11447 | + __m128i m2 = __lsx_vseq_b(word, mask2); |
| 11448 | + __m128i m3 = __lsx_vseq_b(word, mask3); |
| 11449 | + __m128i m4 = __lsx_vseq_b(word, mask4); |
| 11450 | + __m128i m5 = __lsx_vseq_b(word, mask5); |
| 11451 | + __m128i m = |
| 11452 | + __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5); |
| 11453 | + int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
| 11454 | + if (mask != 0) { |
| 11455 | + return i + trailing_zeroes(mask); |
| 11456 | + } |
| 11457 | + } |
| 11458 | + if (i < view.size()) { |
| 11459 | + __m128i word = |
| 11460 | + __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0); |
| 11461 | + __m128i m1 = __lsx_vseq_b(word, mask1); |
| 11462 | + __m128i m2 = __lsx_vseq_b(word, mask2); |
| 11463 | + __m128i m3 = __lsx_vseq_b(word, mask3); |
| 11464 | + __m128i m4 = __lsx_vseq_b(word, mask4); |
| 11465 | + __m128i m5 = __lsx_vseq_b(word, mask5); |
| 11466 | + __m128i m = |
| 11467 | + __lsx_vor_v(__lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m3, m4)), m5); |
| 11468 | + int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
| 11469 | + if (mask != 0) { |
| 11470 | + return view.length() - 16 + trailing_zeroes(mask); |
| 11471 | + } |
| 11472 | + } |
| 11473 | + return size_t(view.length()); |
| 11474 | +} |
11388 | 11475 | #else
|
11389 | 11476 | // : / [ \\ ?
|
11390 | 11477 | static constexpr std::array<uint8_t, 256> special_host_delimiters =
|
@@ -11518,6 +11605,53 @@ ada_really_inline size_t find_next_host_delimiter(std::string_view view,
|
11518 | 11605 | }
|
11519 | 11606 | return size_t(view.length());
|
11520 | 11607 | }
|
| 11608 | +#elif ADA_LSX |
| 11609 | +ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
| 11610 | + size_t location) noexcept { |
| 11611 | + // first check for short strings in which case we do it naively. |
| 11612 | + if (view.size() - location < 16) { // slow path |
| 11613 | + for (size_t i = location; i < view.size(); i++) { |
| 11614 | + if (view[i] == ':' || view[i] == '/' || view[i] == '?' || |
| 11615 | + view[i] == '[') { |
| 11616 | + return i; |
| 11617 | + } |
| 11618 | + } |
| 11619 | + return size_t(view.size()); |
| 11620 | + } |
| 11621 | + // fast path for long strings (expected to be common) |
| 11622 | + size_t i = location; |
| 11623 | + const __m128i mask1 = __lsx_vrepli_b(':'); |
| 11624 | + const __m128i mask2 = __lsx_vrepli_b('/'); |
| 11625 | + const __m128i mask4 = __lsx_vrepli_b('?'); |
| 11626 | + const __m128i mask5 = __lsx_vrepli_b('['); |
| 11627 | + |
| 11628 | + for (; i + 15 < view.size(); i += 16) { |
| 11629 | + __m128i word = __lsx_vld((const __m128i*)(view.data() + i), 0); |
| 11630 | + __m128i m1 = __lsx_vseq_b(word, mask1); |
| 11631 | + __m128i m2 = __lsx_vseq_b(word, mask2); |
| 11632 | + __m128i m4 = __lsx_vseq_b(word, mask4); |
| 11633 | + __m128i m5 = __lsx_vseq_b(word, mask5); |
| 11634 | + __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5)); |
| 11635 | + int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
| 11636 | + if (mask != 0) { |
| 11637 | + return i + trailing_zeroes(mask); |
| 11638 | + } |
| 11639 | + } |
| 11640 | + if (i < view.size()) { |
| 11641 | + __m128i word = |
| 11642 | + __lsx_vld((const __m128i*)(view.data() + view.length() - 16), 0); |
| 11643 | + __m128i m1 = __lsx_vseq_b(word, mask1); |
| 11644 | + __m128i m2 = __lsx_vseq_b(word, mask2); |
| 11645 | + __m128i m4 = __lsx_vseq_b(word, mask4); |
| 11646 | + __m128i m5 = __lsx_vseq_b(word, mask5); |
| 11647 | + __m128i m = __lsx_vor_v(__lsx_vor_v(m1, m2), __lsx_vor_v(m4, m5)); |
| 11648 | + int mask = __lsx_vpickve2gr_hu(__lsx_vmsknz_b(m), 0); |
| 11649 | + if (mask != 0) { |
| 11650 | + return view.length() - 16 + trailing_zeroes(mask); |
| 11651 | + } |
| 11652 | + } |
| 11653 | + return size_t(view.length()); |
| 11654 | +} |
11521 | 11655 | #else
|
11522 | 11656 | // : / [ ?
|
11523 | 11657 | static constexpr std::array<uint8_t, 256> host_delimiters = []() consteval {
|
@@ -11762,8 +11896,8 @@ ada_really_inline void parse_prepared_path(std::string_view input,
|
11762 | 11896 | ? path_buffer_tmp
|
11763 | 11897 | : path_view;
|
11764 | 11898 | if (unicode::is_double_dot_path_segment(path_buffer)) {
|
11765 |
| - if ((helpers::shorten_path(path, type) || special) && |
11766 |
| - location == std::string_view::npos) { |
| 11899 | + helpers::shorten_path(path, type); |
| 11900 | + if (location == std::string_view::npos) { |
11767 | 11901 | path += '/';
|
11768 | 11902 | }
|
11769 | 11903 | } else if (unicode::is_single_dot_path_segment(path_buffer) &&
|
@@ -15318,8 +15452,8 @@ inline void url_aggregator::consume_prepared_path(std::string_view input) {
|
15318 | 15452 | ? path_buffer_tmp
|
15319 | 15453 | : path_view;
|
15320 | 15454 | if (unicode::is_double_dot_path_segment(path_buffer)) {
|
15321 |
| - if ((helpers::shorten_path(path, type) || special) && |
15322 |
| - location == std::string_view::npos) { |
| 15455 | + helpers::shorten_path(path, type); |
| 15456 | + if (location == std::string_view::npos) { |
15323 | 15457 | path += '/';
|
15324 | 15458 | }
|
15325 | 15459 | } else if (unicode::is_single_dot_path_segment(path_buffer) &&
|
|
0 commit comments