1#![deny(warnings)]
2#![cfg_attr(feature = "hints", feature(core_intrinsics))]
3#![cfg_attr(feature = "portable", feature(portable_simd))]
4#![warn(unused_extern_crates)]
5#![deny(
6 clippy::all,
7 clippy::unwrap_used,
8 clippy::unnecessary_unwrap,
9 clippy::pedantic,
10 missing_docs
11)]
12#![allow(
13 clippy::module_name_repetitions,
14 unused_unsafe, )]
16#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
17
18#[cfg(feature = "serde_impl")]
19extern crate serde as serde_ext;
20
21#[cfg(feature = "serde_impl")]
22pub mod serde;
24
25#[cfg(test)]
26pub mod tests;
28
29#[cfg(feature = "serde_impl")]
30pub use crate::serde::{
31 from_reader, from_slice, from_str, to_string, to_string_pretty, to_vec, to_vec_pretty,
32 to_writer, to_writer_pretty,
33};
34
35pub mod prelude;
37
38mod charutils;
39#[macro_use]
40mod macros;
41mod error;
42mod numberparse;
43mod safer_unchecked;
44mod stringparse;
45
46#[allow(unused_imports)]
47use macros::static_cast_u64;
48use safer_unchecked::GetSaferUnchecked;
49use stage2::StackState;
50use tape::Value;
51
52mod impls;
53
54pub mod cow;
56
57pub(crate) const SIMDJSON_PADDING: usize = 32; pub(crate) const SIMDINPUT_LENGTH: usize = 64;
61
62pub const DEFAULT_MAX_DEPTH: usize = 1024;
65
66mod stage2;
67pub mod value;
69
70use std::mem::MaybeUninit;
71use std::{alloc::dealloc, mem};
72pub use value_trait::StaticNode;
73
74pub use crate::error::{Error, ErrorType};
75#[doc(inline)]
76pub use crate::value::*;
77pub use value_trait::ValueType;
78
79pub type Result<T> = std::result::Result<T, Error>;
81
82#[cfg(feature = "known-key")]
83mod known_key;
84#[cfg(feature = "known-key")]
85pub use known_key::{Error as KnownKeyError, KnownKey, KnownKeyTarget, KnownKeyTargetMut};
86
87pub use crate::tape::{Node, Tape};
88use std::alloc::{Layout, alloc, handle_alloc_error};
89use std::ops::{Deref, DerefMut};
90use std::ptr::NonNull;
91
92use simdutf8::basic::imp::ChunkedUtf8Validator;
93
94pub struct Buffers {
96 string_buffer: Vec<u8>,
97 structural_indexes: Vec<u32>,
98 input_buffer: AlignedBuf,
99 stage2_stack: Vec<StackState>,
100 max_depth: usize,
101}
102
103impl Default for Buffers {
104 #[cfg_attr(not(feature = "no-inline"), inline)]
105 fn default() -> Self {
106 Self::new(128)
107 }
108}
109
110impl Buffers {
111 #[cfg_attr(not(feature = "no-inline"), inline)]
121 #[must_use]
122 pub fn structural_indexes(&self) -> &[u32] {
123 &self.structural_indexes
124 }
125
126 #[cfg_attr(not(feature = "no-inline"), inline)]
129 #[must_use]
130 pub fn new(input_len: usize) -> Self {
131 Self::with_max_depth(input_len, DEFAULT_MAX_DEPTH)
132 }
133
134 #[cfg_attr(not(feature = "no-inline"), inline)]
137 #[must_use]
138 pub fn with_max_depth(input_len: usize, max_depth: usize) -> Self {
139 let heuristic_index_cout = input_len / 128;
141 Self {
142 string_buffer: Vec::with_capacity(input_len + SIMDJSON_PADDING),
143 structural_indexes: Vec::with_capacity(heuristic_index_cout),
144 input_buffer: AlignedBuf::with_capacity(input_len + SIMDJSON_PADDING * 2),
145 stage2_stack: Vec::with_capacity(heuristic_index_cout),
146 max_depth,
147 }
148 }
149}
150
151#[cfg_attr(not(feature = "no-inline"), inline)]
156pub fn to_tape(s: &mut [u8]) -> Result<Tape<'_>> {
157 Deserializer::from_slice(s).map(Deserializer::into_tape)
158}
159
160#[cfg_attr(not(feature = "no-inline"), inline)]
165pub fn to_tape_with_buffers<'de>(s: &'de mut [u8], buffers: &mut Buffers) -> Result<Tape<'de>> {
166 Deserializer::from_slice_with_buffers(s, buffers).map(Deserializer::into_tape)
167}
168
169#[cfg_attr(not(feature = "no-inline"), inline)]
174pub fn fill_tape<'de>(s: &'de mut [u8], buffers: &mut Buffers, tape: &mut Tape<'de>) -> Result<()> {
175 tape.0.clear();
176 Deserializer::fill_tape(s, buffers, &mut tape.0)
177}
178
179pub const INPUT_PADDING: usize = SIMDINPUT_LENGTH;
182
183#[cfg_attr(not(feature = "no-inline"), inline)]
225pub fn fill_tape_padded<'de>(
226 s: &'de mut [u8],
227 len: usize,
228 buffers: &mut Buffers,
229 tape: &mut Tape<'de>,
230) -> Result<()> {
231 tape.0.clear();
232 Deserializer::fill_tape_padded(s, len, buffers, &mut tape.0)
233}
234
235pub(crate) trait Stage1Parse {
236 type Utf8Validator: ChunkedUtf8Validator;
237 type SimdRepresentation;
238
239 unsafe fn new(ptr: &[u8]) -> Self;
240
241 unsafe fn compute_quote_mask(quote_bits: u64) -> u64;
242
243 unsafe fn cmp_mask_against_input(&self, m: u8) -> u64;
244
245 unsafe fn unsigned_lteq_against_input(&self, maxval: Self::SimdRepresentation) -> u64;
246
247 unsafe fn find_whitespace_and_structurals(&self, whitespace: &mut u64, structurals: &mut u64);
248
249 unsafe fn flatten_bits(base: &mut Vec<u32>, idx: u32, bits: u64);
250
251 #[cfg_attr(not(feature = "no-inline"), inline)]
263 fn find_quote_mask_and_bits(
264 &self,
265 odd_ends: u64,
266 prev_iter_inside_quote: &mut u64,
267 quote_bits: &mut u64,
268 error_mask: &mut u64,
269 ) -> u64 {
270 unsafe {
271 *quote_bits = self.cmp_mask_against_input(b'"');
272 *quote_bits &= !odd_ends;
273 let mut quote_mask: u64 = Self::compute_quote_mask(*quote_bits);
275 quote_mask ^= *prev_iter_inside_quote;
276 let unescaped: u64 = self.unsigned_lteq_against_input(Self::fill_s8(0x1F));
282 *error_mask |= quote_mask & unescaped;
283 *prev_iter_inside_quote = static_cast_u64!(static_cast_i64!(quote_mask) >> 63);
287 quote_mask
288 }
289 }
290
291 #[cfg_attr(not(feature = "no-inline"), inline)]
301 fn find_odd_backslash_sequences(&self, prev_iter_ends_odd_backslash: &mut u64) -> u64 {
302 const EVEN_BITS: u64 = 0x5555_5555_5555_5555;
303 const ODD_BITS: u64 = !EVEN_BITS;
304
305 let bs_bits: u64 = unsafe { self.cmp_mask_against_input(b'\\') };
306 let start_edges: u64 = bs_bits & !(bs_bits << 1);
307 let even_start_mask: u64 = EVEN_BITS ^ *prev_iter_ends_odd_backslash;
310 let even_starts: u64 = start_edges & even_start_mask;
311 let odd_starts: u64 = start_edges & !even_start_mask;
312 let even_carries: u64 = bs_bits.wrapping_add(even_starts);
313
314 let (mut odd_carries, iter_ends_odd_backslash) = bs_bits.overflowing_add(odd_starts);
318
319 odd_carries |= *prev_iter_ends_odd_backslash;
320 *prev_iter_ends_odd_backslash = u64::from(iter_ends_odd_backslash);
324 let even_carry_ends: u64 = even_carries & !bs_bits;
325 let odd_carry_ends: u64 = odd_carries & !bs_bits;
326 let even_start_odd_end: u64 = even_carry_ends & ODD_BITS;
327 let odd_start_even_end: u64 = odd_carry_ends & EVEN_BITS;
328 let odd_ends: u64 = even_start_odd_end | odd_start_even_end;
329 odd_ends
330 }
331
332 #[cfg_attr(not(feature = "no-inline"), inline)]
339 fn finalize_structurals(
340 mut structurals: u64,
341 whitespace: u64,
342 quote_mask: u64,
343 quote_bits: u64,
344 prev_iter_ends_pseudo_pred: &mut u64,
345 ) -> u64 {
346 structurals &= !quote_mask;
348 structurals |= quote_bits;
351 let pseudo_pred: u64 = structurals | whitespace;
362
363 let shifted_pseudo_pred: u64 = (pseudo_pred << 1) | *prev_iter_ends_pseudo_pred;
364 *prev_iter_ends_pseudo_pred = pseudo_pred >> 63;
365 let pseudo_structurals: u64 = shifted_pseudo_pred & (!whitespace) & (!quote_mask);
366 structurals |= pseudo_structurals;
367
368 structurals &= !(quote_bits & !quote_mask);
371 structurals
372 }
373
374 unsafe fn fill_s8(n: i8) -> Self::SimdRepresentation;
375}
376
377#[derive(Debug)]
379pub struct Deserializer<'de> {
380 pub(crate) tape: Vec<Node<'de>>,
383 idx: usize,
384}
385
386#[derive(Debug, Clone, Copy)]
389pub(crate) struct SillyWrapper<'de> {
390 input: *mut u8,
391 _marker: std::marker::PhantomData<&'de ()>,
392}
393
394impl From<*mut u8> for SillyWrapper<'_> {
395 #[cfg_attr(not(feature = "no-inline"), inline)]
396 fn from(input: *mut u8) -> Self {
397 Self {
398 input,
399 _marker: std::marker::PhantomData,
400 }
401 }
402}
403
404#[derive(Debug, Clone, Copy)]
413pub(crate) struct InputView {
414 pub(crate) ptr: *const u8,
415 pub(crate) len: usize,
416}
417
418impl InputView {
419 #[cfg_attr(not(feature = "no-inline"), inline)]
420 pub(crate) fn from_slice(s: &[u8]) -> Self {
421 Self {
422 ptr: s.as_ptr(),
423 len: s.len(),
424 }
425 }
426
427 #[cfg_attr(not(feature = "no-inline"), inline)]
433 pub(crate) unsafe fn get_kinda_unchecked(self, idx: usize) -> u8 {
434 debug_assert!(idx < self.len);
435 unsafe { self.ptr.add(idx).read() }
436 }
437
438 #[cfg_attr(not(feature = "no-inline"), inline)]
445 pub(crate) unsafe fn tail<'a>(self, idx: usize) -> &'a [u8] {
446 debug_assert!(idx <= self.len);
447 unsafe { core::slice::from_raw_parts(self.ptr.add(idx), self.len - idx) }
448 }
449}
450
451#[cfg(all(
452 feature = "runtime-detection",
453 any(target_arch = "x86_64", target_arch = "x86"),
454))] type FnRaw = *mut ();
456#[cfg(all(
457 feature = "runtime-detection",
458 any(target_arch = "x86_64", target_arch = "x86"),
459))]
460type ParseStrFn = for<'invoke, 'de> unsafe fn(
461 SillyWrapper<'de>,
462 InputView,
463 &'invoke mut [MaybeUninit<u8>],
464 usize,
465) -> std::result::Result<&'de str, error::Error>;
466#[cfg(all(
467 feature = "runtime-detection",
468 any(target_arch = "x86_64", target_arch = "x86"),
469))]
470type FindStructuralBitsFn = unsafe fn(
471 input: &[u8],
472 structural_indexes: &mut Vec<u32>,
473) -> std::result::Result<(), ErrorType>;
474
475#[derive(Clone, Copy, Debug, PartialEq, Eq)]
476pub enum Implementation {
478 Native,
480 StdSimd,
482 SSE42,
484 AVX2,
486 NEON,
488 SIMD128,
490}
491
492impl std::fmt::Display for Implementation {
493 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
494 match self {
495 Implementation::Native => write!(f, "Rust Native"),
496 Implementation::StdSimd => write!(f, "std::simd"),
497 Implementation::SSE42 => write!(f, "SSE42"),
498 Implementation::AVX2 => write!(f, "AVX2"),
499 Implementation::NEON => write!(f, "NEON"),
500 Implementation::SIMD128 => write!(f, "SIMD128"),
501 }
502 }
503}
504
505impl Deserializer<'_> {
506 #[cfg(all(
508 feature = "runtime-detection",
509 any(target_arch = "x86_64", target_arch = "x86"),
510 ))]
511 #[must_use]
512 pub fn algorithm() -> Implementation {
513 if std::is_x86_feature_detected!("avx2") && std::is_x86_feature_detected!("pclmulqdq") {
515 Implementation::AVX2
516 } else if std::is_x86_feature_detected!("sse4.2") {
517 Implementation::SSE42
518 } else {
519 #[cfg(feature = "portable")]
520 let r = Implementation::StdSimd;
521 #[cfg(not(feature = "portable"))]
522 let r = Implementation::Native;
523 r
524 }
525 }
526 #[cfg(not(any(
527 all(
528 feature = "runtime-detection",
529 any(target_arch = "x86_64", target_arch = "x86")
530 ),
531 feature = "portable",
532 target_feature = "avx2",
533 target_feature = "sse4.2",
534 target_feature = "simd128",
535 target_arch = "aarch64",
536 )))]
537 #[must_use]
539 pub fn algorithm() -> Implementation {
540 Implementation::Native
541 }
542 #[cfg(all(feature = "portable", not(feature = "runtime-detection")))]
543 #[must_use]
545 pub fn algorithm() -> Implementation {
546 Implementation::StdSimd
547 }
548
549 #[cfg(all(
550 target_feature = "avx2",
551 not(feature = "portable"),
552 not(feature = "runtime-detection"),
553 ))]
554 #[must_use]
556 pub fn algorithm() -> Implementation {
557 Implementation::AVX2
558 }
559
560 #[cfg(all(
561 target_feature = "sse4.2",
562 not(target_feature = "avx2"),
563 not(feature = "runtime-detection"),
564 not(feature = "portable"),
565 ))]
566 #[must_use]
568 pub fn algorithm() -> Implementation {
569 Implementation::SSE42
570 }
571
572 #[cfg(all(target_arch = "aarch64", not(feature = "portable")))]
573 #[must_use]
575 pub fn algorithm() -> Implementation {
576 Implementation::NEON
577 }
578
579 #[cfg(all(target_feature = "simd128", not(feature = "portable")))]
580 #[must_use]
582 pub fn algorithm() -> Implementation {
583 Implementation::SIMD128
584 }
585}
586
587impl<'de> Deserializer<'de> {
588 #[cfg_attr(not(feature = "no-inline"), inline)]
592 #[cfg(all(
593 feature = "runtime-detection",
594 any(target_arch = "x86_64", target_arch = "x86"),
595 ))]
596 pub(crate) fn parse_str_fn() -> ParseStrFn {
597 if std::is_x86_feature_detected!("avx2") {
598 impls::avx2::parse_str
599 } else if std::is_x86_feature_detected!("sse4.2") {
600 impls::sse42::parse_str
601 } else {
602 #[cfg(feature = "portable")]
603 let r = impls::portable::parse_str;
604 #[cfg(not(feature = "portable"))]
605 let r = impls::native::parse_str;
606 r
607 }
608 }
609
610 #[cfg_attr(not(feature = "no-inline"), inline)]
611 #[cfg(all(
612 feature = "runtime-detection",
613 any(target_arch = "x86_64", target_arch = "x86"),
614 ))]
615 #[allow(dead_code)]
618 pub(crate) unsafe fn parse_str_<'invoke>(
619 input: *mut u8,
620 data: InputView,
621 buffer: &'invoke mut [MaybeUninit<u8>],
622 idx: usize,
623 ) -> Result<&'de str>
624 where
625 'de: 'invoke,
626 {
627 let input: SillyWrapper<'de> = SillyWrapper::from(input);
628 unsafe { (Self::parse_str_fn())(input, data, buffer, idx) }
629 }
630 #[cfg_attr(not(feature = "no-inline"), inline)]
631 #[cfg(not(any(
632 all(
633 feature = "runtime-detection",
634 any(target_arch = "x86_64", target_arch = "x86")
635 ),
636 feature = "portable",
637 target_feature = "avx2",
638 target_feature = "sse4.2",
639 target_feature = "simd128",
640 target_arch = "aarch64",
641 )))]
642 pub(crate) unsafe fn parse_str_<'invoke>(
643 input: *mut u8,
644 data: InputView,
645 buffer: &'invoke mut [MaybeUninit<u8>],
646 idx: usize,
647 ) -> Result<&'de str>
648 where
649 'de: 'invoke,
650 {
651 let input: SillyWrapper<'de> = SillyWrapper::from(input);
652 unsafe { impls::native::parse_str(input, data, buffer, idx) }
653 }
654 #[cfg_attr(not(feature = "no-inline"), inline)]
655 #[cfg(all(feature = "portable", not(feature = "runtime-detection")))]
656 pub(crate) unsafe fn parse_str_<'invoke>(
657 input: *mut u8,
658 data: InputView,
659 buffer: &'invoke mut [MaybeUninit<u8>],
660 idx: usize,
661 ) -> Result<&'de str>
662 where
663 'de: 'invoke,
664 {
665 let input: SillyWrapper<'de> = SillyWrapper::from(input);
666 impls::portable::parse_str(input, data, buffer, idx)
667 }
668
669 #[cfg_attr(not(feature = "no-inline"), inline)]
670 #[cfg(all(
671 target_feature = "avx2",
672 not(feature = "portable"),
673 not(feature = "runtime-detection"),
674 ))]
675 pub(crate) unsafe fn parse_str_<'invoke>(
676 input: *mut u8,
677 data: InputView,
678 buffer: &'invoke mut [MaybeUninit<u8>],
679 idx: usize,
680 ) -> Result<&'de str> {
681 let input: SillyWrapper<'de> = SillyWrapper::from(input);
682 unsafe { impls::avx2::parse_str(input, data, buffer, idx) }
683 }
684
685 #[cfg_attr(not(feature = "no-inline"), inline)]
686 #[cfg(all(
687 target_feature = "sse4.2",
688 not(target_feature = "avx2"),
689 not(feature = "runtime-detection"),
690 not(feature = "portable"),
691 ))]
692 pub(crate) unsafe fn parse_str_<'invoke>(
693 input: *mut u8,
694 data: InputView,
695 buffer: &'invoke mut [MaybeUninit<u8>],
696 idx: usize,
697 ) -> Result<&'de str> {
698 let input: SillyWrapper<'de> = SillyWrapper::from(input);
699 unsafe { impls::sse42::parse_str(input, data, buffer, idx) }
700 }
701
702 #[cfg_attr(not(feature = "no-inline"), inline)]
703 #[cfg(all(target_arch = "aarch64", not(feature = "portable")))]
704 pub(crate) unsafe fn parse_str_<'invoke>(
705 input: *mut u8,
706 data: InputView,
707 buffer: &'invoke mut [MaybeUninit<u8>],
708 idx: usize,
709 ) -> Result<&'de str> {
710 let input: SillyWrapper = SillyWrapper::from(input);
711 impls::neon::parse_str(input, data, buffer, idx)
712 }
713 #[cfg_attr(not(feature = "no-inline"), inline)]
714 #[cfg(all(target_feature = "simd128", not(feature = "portable")))]
715 pub(crate) unsafe fn parse_str_<'invoke>(
716 input: *mut u8,
717 data: InputView,
718 buffer: &'invoke mut [MaybeUninit<u8>],
719 idx: usize,
720 ) -> Result<&'de str> {
721 let input: SillyWrapper<'de> = SillyWrapper::from(input);
722 impls::simd128::parse_str(input, data, buffer, idx)
723 }
724}
725
726impl Deserializer<'_> {
728 #[cfg_attr(not(feature = "no-inline"), inline)]
729 #[cfg(all(
732 feature = "runtime-detection",
733 any(target_arch = "x86_64", target_arch = "x86"),
734 not(feature = "portable"),
735 ))]
736 pub(crate) unsafe fn find_structural_bits_native(
737 input: &[u8],
738 structural_indexes: &mut Vec<u32>,
739 ) -> std::result::Result<(), ErrorType> {
740 match core::str::from_utf8(input) {
741 Ok(_) => (),
742 Err(_) => return Err(ErrorType::InvalidUtf8),
743 }
744 unsafe {
745 Self::_find_structural_bits::<impls::native::SimdInput>(input, structural_indexes)
746 }
747 }
748
749 #[cfg_attr(not(feature = "no-inline"), inline)]
750 #[cfg(all(
751 feature = "runtime-detection",
752 any(target_arch = "x86_64", target_arch = "x86"),
753 ))]
754 pub(crate) unsafe fn find_structural_bits(
755 input: &[u8],
756 structural_indexes: &mut Vec<u32>,
757 ) -> std::result::Result<(), ErrorType> {
758 unsafe {
759 use std::sync::atomic::{AtomicPtr, Ordering};
760
761 static FN: AtomicPtr<()> = AtomicPtr::new(get_fastest as FnRaw);
762
763 #[target_feature(enable = "avx2", enable = "pclmulqdq")]
767 unsafe fn find_structural_bits_avx2(
768 input: &[u8],
769 structural_indexes: &mut Vec<u32>,
770 ) -> core::result::Result<(), error::ErrorType> {
771 unsafe {
772 Deserializer::_find_structural_bits::<impls::avx2::SimdInput>(
773 input,
774 structural_indexes,
775 )
776 }
777 }
778
779 #[target_feature(enable = "sse4.2")]
780 unsafe fn find_structural_bits_sse42(
781 input: &[u8],
782 structural_indexes: &mut Vec<u32>,
783 ) -> core::result::Result<(), error::ErrorType> {
784 unsafe {
785 Deserializer::_find_structural_bits::<impls::sse42::SimdInput>(
786 input,
787 structural_indexes,
788 )
789 }
790 }
791
792 #[cfg_attr(not(feature = "no-inline"), inline)]
793 fn get_fastest_available_implementation() -> FindStructuralBitsFn {
794 if std::is_x86_feature_detected!("avx2")
795 && std::is_x86_feature_detected!("pclmulqdq")
796 {
797 find_structural_bits_avx2
798 } else if std::is_x86_feature_detected!("sse4.2") {
799 find_structural_bits_sse42
800 } else {
801 #[cfg(feature = "portable")]
802 let r = Deserializer::_find_structural_bits::<impls::portable::SimdInput>;
803 #[cfg(not(feature = "portable"))]
804 let r = Deserializer::find_structural_bits_native;
805 r
806 }
807 }
808
809 #[cfg_attr(not(feature = "no-inline"), inline)]
810 unsafe fn get_fastest(
811 input: &[u8],
812 structural_indexes: &mut Vec<u32>,
813 ) -> core::result::Result<(), error::ErrorType> {
814 unsafe {
815 let fun = get_fastest_available_implementation();
816 FN.store(fun as FnRaw, Ordering::Relaxed);
817 (fun)(input, structural_indexes)
818 }
819 }
820
821 let fun = FN.load(Ordering::Relaxed);
822 mem::transmute::<FnRaw, FindStructuralBitsFn>(fun)(input, structural_indexes)
823 }
824 }
825
826 #[cfg(not(any(
827 all(
828 feature = "runtime-detection",
829 any(target_arch = "x86_64", target_arch = "x86")
830 ),
831 feature = "portable",
832 target_feature = "avx2",
833 target_feature = "sse4.2",
834 target_feature = "simd128",
835 target_arch = "aarch64",
836 )))]
837 #[cfg_attr(not(feature = "no-inline"), inline)]
838 pub(crate) unsafe fn find_structural_bits(
839 input: &[u8],
840 structural_indexes: &mut Vec<u32>,
841 ) -> std::result::Result<(), ErrorType> {
842 match core::str::from_utf8(input) {
845 Ok(_) => (),
846 Err(_) => return Err(ErrorType::InvalidUtf8),
847 }
848 #[cfg(not(feature = "portable"))]
849 unsafe {
850 Self::_find_structural_bits::<impls::native::SimdInput>(input, structural_indexes)
851 }
852 }
853
854 #[cfg(all(feature = "portable", not(feature = "runtime-detection")))]
855 #[cfg_attr(not(feature = "no-inline"), inline)]
856 pub(crate) unsafe fn find_structural_bits(
857 input: &[u8],
858 structural_indexes: &mut Vec<u32>,
859 ) -> std::result::Result<(), ErrorType> {
860 unsafe {
861 Self::_find_structural_bits::<impls::portable::SimdInput>(input, structural_indexes)
862 }
863 }
864
865 #[cfg(all(
866 target_feature = "avx2",
867 not(feature = "portable"),
868 not(feature = "runtime-detection"),
869 ))]
870 #[cfg_attr(not(feature = "no-inline"), inline)]
871 pub(crate) unsafe fn find_structural_bits(
872 input: &[u8],
873 structural_indexes: &mut Vec<u32>,
874 ) -> std::result::Result<(), ErrorType> {
875 unsafe { Self::_find_structural_bits::<impls::avx2::SimdInput>(input, structural_indexes) }
876 }
877
878 #[cfg(all(
879 target_feature = "sse4.2",
880 not(target_feature = "avx2"),
881 not(feature = "runtime-detection"),
882 not(feature = "portable"),
883 ))]
884 #[cfg_attr(not(feature = "no-inline"), inline)]
885 pub(crate) unsafe fn find_structural_bits(
886 input: &[u8],
887 structural_indexes: &mut Vec<u32>,
888 ) -> std::result::Result<(), ErrorType> {
889 unsafe { Self::_find_structural_bits::<impls::sse42::SimdInput>(input, structural_indexes) }
890 }
891
892 #[cfg(all(target_arch = "aarch64", not(feature = "portable")))]
893 #[cfg_attr(not(feature = "no-inline"), inline)]
894 pub(crate) unsafe fn find_structural_bits(
895 input: &[u8],
896 structural_indexes: &mut Vec<u32>,
897 ) -> std::result::Result<(), ErrorType> {
898 unsafe { Self::_find_structural_bits::<impls::neon::SimdInput>(input, structural_indexes) }
899 }
900
901 #[cfg(all(target_feature = "simd128", not(feature = "portable")))]
902 #[cfg_attr(not(feature = "no-inline"), inline)]
903 pub(crate) unsafe fn find_structural_bits(
904 input: &[u8],
905 structural_indexes: &mut Vec<u32>,
906 ) -> std::result::Result<(), ErrorType> {
907 unsafe {
908 Self::_find_structural_bits::<impls::simd128::SimdInput>(input, structural_indexes)
909 }
910 }
911}
912
913impl<'de> Deserializer<'de> {
914 #[must_use]
917 pub fn from_tape(tape: Tape<'de>) -> Self {
918 Self {
919 tape: tape.0,
920 idx: 0,
921 }
922 }
923
924 #[must_use]
926 pub fn into_tape(self) -> Tape<'de> {
927 Tape(self.tape)
928 }
929
930 #[must_use]
932 pub fn as_value(&self) -> Value<'_, 'de> {
933 Value(&self.tape)
935 }
936
937 pub fn restart(&mut self) {
939 self.idx = 0;
941 }
942
943 #[cold]
944 #[inline(never)]
945 fn error(error: ErrorType) -> Error {
946 Error::new(0, None, error)
947 }
948
949 #[cold]
950 #[inline(never)]
951 fn error_c(idx: usize, c: char, error: ErrorType) -> Error {
952 Error::new(idx, Some(c), error)
953 }
954
955 pub fn from_slice(input: &'de mut [u8]) -> Result<Self> {
961 let len = input.len();
962
963 let mut buffer = Buffers::new(len);
964
965 Self::from_slice_with_buffers(input, &mut buffer)
966 }
967
968 #[allow(clippy::uninit_vec)]
976 #[cfg_attr(not(feature = "no-inline"), inline)]
977 fn fill_tape(
978 input: &'de mut [u8],
979 buffer: &mut Buffers,
980 tape: &mut Vec<Node<'de>>,
981 ) -> Result<()> {
982 const LOTS_OF_SPACES: [u8; SIMDINPUT_LENGTH] = [b' '; SIMDINPUT_LENGTH];
983 let len = input.len();
984 let simd_safe_len = len + SIMDINPUT_LENGTH;
985
986 if len > u32::MAX as usize {
987 return Err(Self::error(ErrorType::InputTooLarge));
988 }
989
990 buffer.string_buffer.clear();
991 buffer.string_buffer.reserve(len + SIMDJSON_PADDING);
992
993 let input_buffer = &mut buffer.input_buffer;
994 if input_buffer.capacity() < simd_safe_len {
995 *input_buffer = AlignedBuf::with_capacity(simd_safe_len);
996 }
997
998 unsafe {
999 input_buffer
1000 .as_mut_ptr()
1001 .copy_from_nonoverlapping(input.as_ptr(), len);
1002
1003 input_buffer
1006 .as_mut_ptr()
1007 .add(len)
1008 .copy_from_nonoverlapping(LOTS_OF_SPACES.as_ptr(), SIMDINPUT_LENGTH);
1009
1010 input_buffer.set_len(simd_safe_len);
1012
1013 Self::find_structural_bits(input, &mut buffer.structural_indexes)
1014 .map_err(Error::generic)?;
1015 };
1016
1017 unsafe {
1020 Self::build_tape(
1021 input.as_mut_ptr(),
1022 InputView::from_slice(input_buffer),
1023 buffer.string_buffer.spare_capacity_mut(),
1024 &buffer.structural_indexes,
1025 &mut buffer.stage2_stack,
1026 buffer.max_depth,
1027 tape,
1028 )
1029 }
1030 }
1031
1032 #[cfg_attr(not(feature = "no-inline"), inline)]
1033 fn fill_tape_padded(
1034 input: &'de mut [u8],
1035 len: usize,
1036 buffer: &mut Buffers,
1037 tape: &mut Vec<Node<'de>>,
1038 ) -> Result<()> {
1039 if input.len().saturating_sub(len) < SIMDINPUT_LENGTH {
1040 return Err(Self::error(ErrorType::InsufficientPadding));
1041 }
1042 if len > u32::MAX as usize {
1043 return Err(Self::error(ErrorType::InputTooLarge));
1044 }
1045
1046 buffer.string_buffer.clear();
1047 buffer.string_buffer.reserve(len + SIMDJSON_PADDING);
1048
1049 let terminator = mem::replace(&mut input[len], b' ');
1052
1053 let ptr = input.as_mut_ptr();
1059 let input2 = InputView {
1060 ptr,
1061 len: input.len(),
1062 };
1063
1064 let stage1 = unsafe {
1065 let head: &[u8] = core::slice::from_raw_parts(ptr, len);
1066 Self::find_structural_bits(head, &mut buffer.structural_indexes)
1067 };
1068 let res = stage1.map_err(Error::generic).and_then(|()| unsafe {
1069 Self::build_tape(
1070 ptr,
1071 input2,
1072 buffer.string_buffer.spare_capacity_mut(),
1073 &buffer.structural_indexes,
1074 &mut buffer.stage2_stack,
1075 buffer.max_depth,
1076 tape,
1077 )
1078 });
1079 unsafe { ptr.add(len).write(terminator) };
1081 res
1082 }
1083
1084 pub fn from_slice_with_buffers(input: &'de mut [u8], buffer: &mut Buffers) -> Result<Self> {
1091 let mut tape: Vec<Node<'de>> = Vec::with_capacity(buffer.structural_indexes.len());
1092
1093 Self::fill_tape(input, buffer, &mut tape)?;
1094
1095 Ok(Self { tape, idx: 0 })
1096 }
1097
1098 #[cfg(feature = "serde_impl")]
1099 #[cfg_attr(not(feature = "no-inline"), inline)]
1100 fn skip(&mut self) {
1101 self.idx += 1;
1102 }
1103
1104 #[cfg_attr(not(feature = "no-inline"), inline)]
1112 pub unsafe fn next_(&mut self) -> Node<'de> {
1113 let r = *unsafe { self.tape.get_kinda_unchecked(self.idx) };
1114 self.idx += 1;
1115 r
1116 }
1117
1118 #[cfg_attr(not(feature = "no-inline"), inline)]
1119 #[allow(clippy::cast_possible_truncation)]
1120 pub(crate) unsafe fn _find_structural_bits<S: Stage1Parse>(
1121 input: &[u8],
1122 structural_indexes: &mut Vec<u32>,
1123 ) -> std::result::Result<(), ErrorType> {
1124 let len = input.len();
1125 structural_indexes.clear();
1128 structural_indexes.reserve(len / 8);
1129
1130 let mut utf8_validator = unsafe { S::Utf8Validator::new() };
1131
1132 let mut prev_iter_ends_odd_backslash: u64 = 0;
1139 let mut prev_iter_inside_quote: u64 = 0;
1141 let mut prev_iter_ends_pseudo_pred: u64 = 1;
1148
1149 let mut structurals: u64 = 0;
1155
1156 let lenminus64: usize = len.saturating_sub(64);
1157 let mut idx: usize = 0;
1158 let mut error_mask: u64 = 0; while idx < lenminus64 {
1161 let chunk = unsafe { input.get_kinda_unchecked(idx..idx + 64) };
1167 unsafe { utf8_validator.update_from_chunks(chunk) };
1168
1169 let input = unsafe { S::new(chunk) };
1170 let odd_ends: u64 =
1172 input.find_odd_backslash_sequences(&mut prev_iter_ends_odd_backslash);
1173
1174 let mut quote_bits: u64 = 0;
1177 let quote_mask: u64 = input.find_quote_mask_and_bits(
1178 odd_ends,
1179 &mut prev_iter_inside_quote,
1180 &mut quote_bits,
1181 &mut error_mask,
1182 );
1183
1184 unsafe { S::flatten_bits(structural_indexes, idx as u32, structurals) };
1187
1188 let mut whitespace: u64 = 0;
1189 unsafe { input.find_whitespace_and_structurals(&mut whitespace, &mut structurals) };
1190
1191 structurals = S::finalize_structurals(
1193 structurals,
1194 whitespace,
1195 quote_mask,
1196 quote_bits,
1197 &mut prev_iter_ends_pseudo_pred,
1198 );
1199 idx += SIMDINPUT_LENGTH;
1200 }
1201
1202 if idx < len {
1206 let mut tmpbuf: [u8; SIMDINPUT_LENGTH] = [0x20; SIMDINPUT_LENGTH];
1207 unsafe {
1208 tmpbuf
1209 .as_mut_ptr()
1210 .copy_from(input.as_ptr().add(idx), len - idx);
1211 };
1212 unsafe { utf8_validator.update_from_chunks(&tmpbuf) };
1213
1214 let input = unsafe { S::new(&tmpbuf) };
1215
1216 let odd_ends: u64 =
1218 input.find_odd_backslash_sequences(&mut prev_iter_ends_odd_backslash);
1219
1220 let mut quote_bits: u64 = 0;
1223 let quote_mask: u64 = input.find_quote_mask_and_bits(
1224 odd_ends,
1225 &mut prev_iter_inside_quote,
1226 &mut quote_bits,
1227 &mut error_mask,
1228 );
1229
1230 unsafe { S::flatten_bits(structural_indexes, idx as u32, structurals) };
1233
1234 let mut whitespace: u64 = 0;
1235 unsafe { input.find_whitespace_and_structurals(&mut whitespace, &mut structurals) };
1236
1237 structurals = S::finalize_structurals(
1239 structurals,
1240 whitespace,
1241 quote_mask,
1242 quote_bits,
1243 &mut prev_iter_ends_pseudo_pred,
1244 );
1245 idx += SIMDINPUT_LENGTH;
1246 }
1247 if prev_iter_inside_quote != 0 {
1249 return Err(ErrorType::Syntax);
1250 }
1251 unsafe { S::flatten_bits(structural_indexes, idx as u32, structurals) };
1253
1254 if structural_indexes.is_empty() {
1257 return Err(ErrorType::Eof);
1258 }
1259
1260 if error_mask != 0 {
1261 return Err(ErrorType::Syntax);
1262 }
1263
1264 if unsafe { utf8_validator.finalize(None).is_err() } {
1265 Err(ErrorType::InvalidUtf8)
1266 } else {
1267 Ok(())
1268 }
1269 }
1270}
1271
1272struct AlignedBuf {
1274 layout: Layout,
1275 capacity: usize,
1276 len: usize,
1277 inner: NonNull<u8>,
1278}
1279unsafe impl Send for AlignedBuf {}
1286unsafe impl Sync for AlignedBuf {}
1287impl AlignedBuf {
1288 #[must_use]
1290 pub fn with_capacity(capacity: usize) -> Self {
1291 if capacity == 0 {
1292 let layout = Layout::from_size_align(0, SIMDJSON_PADDING)
1293 .expect("Layout for size 0 should always be valid");
1294 return Self {
1295 layout,
1296 capacity: 0,
1297 len: 0,
1298 inner: NonNull::dangling(),
1299 };
1300 }
1301 let Ok(layout) = Layout::from_size_align(capacity, SIMDJSON_PADDING) else {
1302 Self::capacity_overflow()
1303 };
1304 if mem::size_of::<usize>() < 8 && capacity > isize::MAX as usize {
1305 Self::capacity_overflow()
1306 }
1307 unsafe {
1308 let Some(inner) = NonNull::new(alloc(layout)) else {
1309 handle_alloc_error(layout)
1310 };
1311 Self {
1312 layout,
1313 capacity,
1314 len: 0,
1315 inner,
1316 }
1317 }
1318 }
1319
1320 fn as_mut_ptr(&mut self) -> *mut u8 {
1321 self.inner.as_ptr()
1322 }
1323
1324 fn capacity_overflow() -> ! {
1325 panic!("capacity overflow");
1326 }
1327 fn capacity(&self) -> usize {
1328 self.capacity
1329 }
1330 unsafe fn set_len(&mut self, n: usize) {
1331 assert!(
1332 n <= self.capacity,
1333 "New size ({}) can not be larger then capacity ({}).",
1334 n,
1335 self.capacity
1336 );
1337 self.len = n;
1338 }
1339}
1340impl Drop for AlignedBuf {
1341 fn drop(&mut self) {
1342 if self.capacity > 0 {
1343 unsafe {
1344 dealloc(self.inner.as_ptr(), self.layout);
1345 }
1346 }
1347 }
1348}
1349
1350impl Deref for AlignedBuf {
1351 type Target = [u8];
1352
1353 fn deref(&self) -> &Self::Target {
1354 unsafe { std::slice::from_raw_parts(self.inner.as_ptr(), self.len) }
1355 }
1356}
1357
1358impl DerefMut for AlignedBuf {
1359 fn deref_mut(&mut self) -> &mut Self::Target {
1360 unsafe { std::slice::from_raw_parts_mut(self.inner.as_ptr(), self.len) }
1361 }
1362}