Skip to content

Commit d5ed064

Browse files
committed
forbid unsafe impl, restructure
1 parent f088015 commit d5ed064

File tree

9 files changed

+102
-149
lines changed

9 files changed

+102
-149
lines changed

portable/src/basic.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub mod imp {
115115
/// This implementation requires CPU SIMD features specified by the module it resides in.
116116
/// It is undefined behavior to call it if the required CPU features are not available.
117117
#[must_use]
118-
unsafe fn new() -> Self
118+
fn new() -> Self
119119
where
120120
Self: Sized;
121121

@@ -124,7 +124,7 @@ pub mod imp {
124124
/// # Safety
125125
/// This implementation requires CPU SIMD features specified by the module it resides in.
126126
/// It is undefined behavior to call it if the required CPU features are not available.
127-
unsafe fn update(&mut self, input: &[u8]);
127+
fn update(&mut self, input: &[u8]);
128128

129129
/// Finishes the validation and returns `Ok(())` if the input was valid UTF-8.
130130
///
@@ -135,7 +135,7 @@ pub mod imp {
135135
/// # Safety
136136
/// This implementation requires CPU SIMD features specified by the module it resides in.
137137
/// It is undefined behavior to call it if the required CPU features are not available.
138-
unsafe fn finalize(self) -> core::result::Result<(), basic::Utf8Error>;
138+
fn finalize(self) -> core::result::Result<(), basic::Utf8Error>;
139139
}
140140

141141
/// Like [`Utf8Validator`] this low-level API is for streaming validation of UTF-8 data.
@@ -162,7 +162,7 @@ pub mod imp {
162162
/// This implementation requires CPU SIMD features specified by the module it resides in.
163163
/// It is undefined behavior to call it if the required CPU features are not available.
164164
#[must_use]
165-
unsafe fn new() -> Self
165+
fn new() -> Self
166166
where
167167
Self: Sized;
168168

@@ -174,7 +174,7 @@ pub mod imp {
174174
/// # Safety
175175
/// This implementation requires CPU SIMD features specified by the module it resides in.
176176
/// It is undefined behavior to call it if the required CPU features are not available.
177-
unsafe fn update_from_chunks(&mut self, input: &[u8]);
177+
fn update_from_chunks(&mut self, input: &[u8]);
178178

179179
/// Updates the validator with remaining input if any. There is no restriction on the
180180
/// data provided.
@@ -188,26 +188,26 @@ pub mod imp {
188188
/// # Safety
189189
/// This implementation requires CPU SIMD features specified by the module it resides in.
190190
/// It is undefined behavior to call it if the required CPU features are not available.
191-
unsafe fn finalize(
191+
fn finalize(
192192
self,
193193
remaining_input: core::option::Option<&[u8]>,
194194
) -> core::result::Result<(), basic::Utf8Error>;
195195
}
196196

197-
/// Includes the portable SIMD implementations.
198-
pub mod portable {
199-
/// Includes the validation implementation using 128-bit portable SIMD.
200-
pub mod simd128 {
201-
pub use crate::implementation::portable::simd128::validate_utf8_basic as validate_utf8;
202-
pub use crate::implementation::portable::simd128::ChunkedUtf8ValidatorImp;
203-
pub use crate::implementation::portable::simd128::Utf8ValidatorImp;
204-
}
205-
206-
/// Includes the validation implementation using 256-bit portable SIMD.
207-
pub mod simd256 {
208-
pub use crate::implementation::portable::simd256::validate_utf8_basic as validate_utf8;
209-
pub use crate::implementation::portable::simd256::ChunkedUtf8ValidatorImp;
210-
pub use crate::implementation::portable::simd256::Utf8ValidatorImp;
211-
}
197+
/// Best for current target
198+
pub use v128 as auto;
199+
200+
/// Includes the validation implementation using 128-bit portable SIMD.
201+
pub mod v128 {
202+
pub use crate::implementation::simd::v128::validate_utf8_basic as validate_utf8;
203+
pub use crate::implementation::simd::v128::ChunkedUtf8ValidatorImp;
204+
pub use crate::implementation::simd::v128::Utf8ValidatorImp;
205+
}
206+
207+
/// Includes the validation implementation using 256-bit portable SIMD.
208+
pub mod v256 {
209+
pub use crate::implementation::simd::v256::validate_utf8_basic as validate_utf8;
210+
pub use crate::implementation::simd::v256::ChunkedUtf8ValidatorImp;
211+
pub use crate::implementation::simd::v256::Utf8ValidatorImp;
212212
}
213213
}

portable/src/compat.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,16 @@ pub fn from_utf8_mut(input: &mut [u8]) -> Result<&mut str, Utf8Error> {
102102
/// Allows direct access to the platform-specific unsafe validation implementations.
103103
#[cfg(feature = "public_imp")]
104104
pub mod imp {
105-
/// FIXME: add docs
106-
pub mod portable {
107-
/// Includes the validation implementation for 128-bit portable SIMD.
108-
pub mod simd128 {
109-
pub use crate::implementation::portable::simd128::validate_utf8_compat as validate_utf8;
110-
}
105+
/// Best for current target FIXME: 256-bit support
106+
pub use v128 as auto;
111107

112-
/// Includes the validation implementation for 256-bit portable SIMD.
113-
pub mod simd256 {
114-
pub use crate::implementation::portable::simd256::validate_utf8_compat as validate_utf8;
115-
}
108+
/// Includes the validation implementation for 128-bit portable SIMD.
109+
pub mod v128 {
110+
pub use crate::implementation::simd::v128::validate_utf8_compat as validate_utf8;
111+
}
112+
113+
/// Includes the validation implementation for 256-bit portable SIMD.
114+
pub mod v256 {
115+
pub use crate::implementation::simd::v256::validate_utf8_compat as validate_utf8;
116116
}
117117
}

portable/src/implementation/helpers.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,6 @@ pub(crate) fn get_compat_error(input: &[u8], failing_block_pos: usize) -> Utf8Er
3737
validate_utf8_at_offset(input, offset).unwrap_err()
3838
}
3939

40-
#[allow(dead_code)] // only used if there is a SIMD implementation
41-
#[inline]
42-
pub(crate) unsafe fn memcpy_unaligned_nonoverlapping_inline_opt_lt_64(
43-
src: *const u8,
44-
dest: *mut u8,
45-
len: usize,
46-
) {
47-
src.copy_to_nonoverlapping(dest, len);
48-
}
49-
5040
pub(crate) const SIMD_CHUNK_SIZE: usize = 64;
5141

5242
#[repr(C, align(32))]

portable/src/implementation/mod.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! Contains UTF-8 validation implementations.
22
3-
pub(crate) mod helpers;
3+
#![forbid(unsafe_code)]
44

5-
// UTF-8 validation function types
6-
pub(crate) mod portable;
5+
pub(crate) mod helpers;
6+
pub(crate) mod simd;
77

88
#[inline]
9-
pub(crate) unsafe fn validate_utf8_basic(input: &[u8]) -> Result<(), crate::basic::Utf8Error> {
9+
pub(crate) fn validate_utf8_basic(input: &[u8]) -> Result<(), crate::basic::Utf8Error> {
1010
if input.len() < helpers::SIMD_CHUNK_SIZE {
1111
return validate_utf8_basic_fallback(input);
1212
}
@@ -15,27 +15,27 @@ pub(crate) unsafe fn validate_utf8_basic(input: &[u8]) -> Result<(), crate::basi
1515
}
1616

1717
#[inline(never)]
18-
unsafe fn validate_utf8_basic_simd(input: &[u8]) -> Result<(), crate::basic::Utf8Error> {
18+
fn validate_utf8_basic_simd(input: &[u8]) -> Result<(), crate::basic::Utf8Error> {
1919
#[cfg(not(feature = "simd256"))]
20-
return portable::algorithm_safe::validate_utf8_basic(input);
20+
return simd::v128::validate_utf8_basic(input);
2121
#[cfg(feature = "simd256")]
22-
return portable::simd256::validate_utf8_basic(input);
22+
return simd::v256::validate_utf8_basic(input);
2323
}
2424

2525
#[inline]
26-
pub(crate) unsafe fn validate_utf8_compat(input: &[u8]) -> Result<(), crate::compat::Utf8Error> {
26+
pub(crate) fn validate_utf8_compat(input: &[u8]) -> Result<(), crate::compat::Utf8Error> {
2727
if input.len() < helpers::SIMD_CHUNK_SIZE {
2828
return validate_utf8_compat_fallback(input);
2929
}
3030

3131
validate_utf8_compat_simd(input)
3232
}
3333

34-
unsafe fn validate_utf8_compat_simd(input: &[u8]) -> Result<(), crate::compat::Utf8Error> {
34+
fn validate_utf8_compat_simd(input: &[u8]) -> Result<(), crate::compat::Utf8Error> {
3535
#[cfg(not(feature = "simd256"))]
36-
return portable::algorithm_safe::validate_utf8_compat(input);
36+
return simd::v128::validate_utf8_compat(input);
3737
#[cfg(feature = "simd256")]
38-
return portable::simd256::validate_utf8_compat(input);
38+
return simd::v256::validate_utf8_compat(input);
3939
}
4040

4141
// fallback method implementations

portable/src/implementation/portable/mod.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

portable/src/implementation/portable/simd128.rs

Lines changed: 0 additions & 4 deletions
This file was deleted.

portable/src/implementation/portable/simd256.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.

portable/src/implementation/portable/algorithm_safe.rs renamed to portable/src/implementation/simd.rs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -658,11 +658,6 @@ where
658658
///
659659
/// # Errors
660660
/// Returns the zero-sized [`basic::Utf8Error`] on failure.
661-
///
662-
/// # Safety
663-
/// This function is inherently unsafe because it is compiled with SIMD extensions
664-
/// enabled. Make sure that the CPU supports it before calling.
665-
///
666661
#[inline]
667662
pub fn validate_utf8_basic(input: &[u8]) -> core::result::Result<(), basic::Utf8Error> {
668663
Utf8CheckAlgorithm::<16, 4>::validate_utf8_basic(input)
@@ -672,11 +667,6 @@ pub fn validate_utf8_basic(input: &[u8]) -> core::result::Result<(), basic::Utf8
672667
///
673668
/// # Errors
674669
/// Returns [`compat::Utf8Error`] with detailed error information on failure.
675-
///
676-
/// # Safety
677-
/// This function is inherently unsafe because it is compiled with SIMD extensions
678-
/// enabled. Make sure that the CPU supports it before calling.
679-
///
680670
#[inline]
681671
pub fn validate_utf8_compat(input: &[u8]) -> core::result::Result<(), compat::Utf8Error> {
682672
Utf8CheckAlgorithm::<16, 4>::validate_utf8_compat_simd0(input)
@@ -698,7 +688,7 @@ pub struct Utf8ValidatorImp {
698688
#[cfg(feature = "public_imp")]
699689
impl Utf8ValidatorImp {
700690
#[inline]
701-
unsafe fn update_from_incomplete_data(&mut self) {
691+
fn update_from_incomplete_data(&mut self) {
702692
let simd_input = SimdInput::new(&self.incomplete_data);
703693
self.algorithm.check_utf8(&simd_input);
704694
self.incomplete_len = 0;
@@ -709,7 +699,7 @@ impl Utf8ValidatorImp {
709699
impl basic::imp::Utf8Validator for Utf8ValidatorImp {
710700
#[inline]
711701
#[must_use]
712-
unsafe fn new() -> Self {
702+
fn new() -> Self {
713703
Self {
714704
algorithm: Utf8CheckAlgorithm::<16, 4>::new(),
715705
incomplete_data: [0; 64],
@@ -718,17 +708,15 @@ impl basic::imp::Utf8Validator for Utf8ValidatorImp {
718708
}
719709

720710
#[inline]
721-
unsafe fn update(&mut self, mut input: &[u8]) {
711+
fn update(&mut self, mut input: &[u8]) {
722712
use crate::implementation::helpers::SIMD_CHUNK_SIZE;
723713
if input.is_empty() {
724714
return;
725715
}
726716
if self.incomplete_len != 0 {
727717
let to_copy = core::cmp::min(SIMD_CHUNK_SIZE - self.incomplete_len, input.len());
728-
self.incomplete_data
729-
.as_mut_ptr()
730-
.add(self.incomplete_len)
731-
.copy_from_nonoverlapping(input.as_ptr(), to_copy);
718+
self.incomplete_data[self.incomplete_len..self.incomplete_len + to_copy]
719+
.copy_from_slice(&input[..to_copy]);
732720
if self.incomplete_len + to_copy == SIMD_CHUNK_SIZE {
733721
self.update_from_incomplete_data();
734722
input = &input[to_copy..];
@@ -747,15 +735,13 @@ impl basic::imp::Utf8Validator for Utf8ValidatorImp {
747735
}
748736
if idx < len {
749737
let to_copy = len - idx;
750-
self.incomplete_data
751-
.as_mut_ptr()
752-
.copy_from_nonoverlapping(input.as_ptr().add(idx), to_copy);
738+
self.incomplete_data[..to_copy].copy_from_slice(&input[idx..idx + to_copy]);
753739
self.incomplete_len = to_copy;
754740
}
755741
}
756742

757743
#[inline]
758-
unsafe fn finalize(mut self) -> core::result::Result<(), basic::Utf8Error> {
744+
fn finalize(mut self) -> core::result::Result<(), basic::Utf8Error> {
759745
if self.incomplete_len != 0 {
760746
for i in &mut self.incomplete_data[self.incomplete_len..] {
761747
*i = 0;
@@ -785,14 +771,14 @@ pub struct ChunkedUtf8ValidatorImp {
785771
impl basic::imp::ChunkedUtf8Validator for ChunkedUtf8ValidatorImp {
786772
#[inline]
787773
#[must_use]
788-
unsafe fn new() -> Self {
774+
fn new() -> Self {
789775
Self {
790776
algorithm: Utf8CheckAlgorithm::<16, 4>::new(),
791777
}
792778
}
793779

794780
#[inline]
795-
unsafe fn update_from_chunks(&mut self, input: &[u8]) {
781+
fn update_from_chunks(&mut self, input: &[u8]) {
796782
use crate::implementation::helpers::SIMD_CHUNK_SIZE;
797783

798784
assert!(
@@ -806,7 +792,7 @@ impl basic::imp::ChunkedUtf8Validator for ChunkedUtf8ValidatorImp {
806792
}
807793

808794
#[inline]
809-
unsafe fn finalize(
795+
fn finalize(
810796
mut self,
811797
remaining_input: core::option::Option<&[u8]>,
812798
) -> core::result::Result<(), basic::Utf8Error> {
@@ -823,10 +809,7 @@ impl basic::imp::ChunkedUtf8Validator for ChunkedUtf8ValidatorImp {
823809
if rem > 0 {
824810
remaining_input = &remaining_input[chunks_lim..];
825811
let mut tmpbuf = TempSimdChunk::new();
826-
tmpbuf
827-
.0
828-
.as_mut_ptr()
829-
.copy_from_nonoverlapping(remaining_input.as_ptr(), remaining_input.len());
812+
tmpbuf.0[..remaining_input.len()].copy_from_slice(remaining_input);
830813
let simd_input = SimdInput::new(&tmpbuf.0);
831814
self.algorithm.check_utf8(&simd_input);
832815
}
@@ -840,3 +823,21 @@ impl basic::imp::ChunkedUtf8Validator for ChunkedUtf8ValidatorImp {
840823
}
841824
}
842825
}
826+
827+
pub(crate) mod v128 {
828+
pub use super::validate_utf8_basic;
829+
pub use super::validate_utf8_compat;
830+
#[cfg(feature = "public_imp")]
831+
pub use super::ChunkedUtf8ValidatorImp;
832+
#[cfg(feature = "public_imp")]
833+
pub use super::Utf8ValidatorImp;
834+
}
835+
836+
pub(crate) mod v256 {
837+
pub use super::validate_utf8_basic;
838+
pub use super::validate_utf8_compat;
839+
#[cfg(feature = "public_imp")]
840+
pub use super::ChunkedUtf8ValidatorImp;
841+
#[cfg(feature = "public_imp")]
842+
pub use super::Utf8ValidatorImp;
843+
}

0 commit comments

Comments
 (0)