Skip to content

Commit c0c7289

Browse files
committed
rm unsafe
1 parent b7d0bc8 commit c0c7289

File tree

1 file changed

+37
-59
lines changed

1 file changed

+37
-59
lines changed

portable/src/implementation/portable/algorithm_new.rs

Lines changed: 37 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use core::{hint::assert_unchecked, slice};
21
use std::simd::{
32
cmp::SimdPartialOrd,
43
num::{SimdInt, SimdUint},
@@ -43,46 +42,37 @@ where
4342
}
4443

4544
trait SimdInputTrait {
46-
fn new(ptr: *const u8) -> Self;
47-
fn is_ascii(&self) -> bool;
48-
fn new_partial_masked_load(ptr: *const u8, len: usize) -> Self;
49-
fn new_partial_copy(ptr: *const u8, len: usize) -> Self;
50-
fn new_partial(ptr: *const u8, len: usize) -> Self
45+
fn new(ptr: &[u8]) -> Self;
46+
fn new_partial_masked_load(slice: &[u8]) -> Self;
47+
fn new_partial_copy(slice: &[u8]) -> Self;
48+
fn new_partial(slice: &[u8]) -> Self
5149
where
5250
Self: Sized,
5351
{
5452
if HAS_FAST_MASKED_LOAD {
55-
Self::new_partial_masked_load(ptr, len)
53+
Self::new_partial_masked_load(slice)
5654
} else {
57-
Self::new_partial_copy(ptr, len)
55+
Self::new_partial_copy(slice)
5856
}
5957
}
58+
fn is_ascii(&self) -> bool;
6059
}
6160

6261
impl SimdInputTrait for SimdInput<16, 4> {
6362
#[inline]
64-
fn new(ptr: *const u8) -> Self {
65-
#[expect(clippy::cast_ptr_alignment)]
66-
let ptr = ptr.cast::<u8x16>();
67-
unsafe {
68-
Self {
69-
vals: [
70-
ptr.read_unaligned(),
71-
ptr.add(1).read_unaligned(),
72-
ptr.add(2).read_unaligned(),
73-
ptr.add(3).read_unaligned(),
74-
],
75-
}
63+
fn new(s: &[u8]) -> Self {
64+
Self {
65+
vals: [
66+
u8x16::from_slice(&s[..16]),
67+
u8x16::from_slice(&s[16..32]),
68+
u8x16::from_slice(&s[32..48]),
69+
u8x16::from_slice(&s[48..64]),
70+
],
7671
}
7772
}
7873

7974
#[inline]
80-
fn new_partial_masked_load(ptr: *const u8, len: usize) -> Self {
81-
unsafe {
82-
assert_unchecked(len > 0);
83-
assert_unchecked(len < 64);
84-
}
85-
let mut slice = unsafe { slice::from_raw_parts(ptr, len) };
75+
fn new_partial_masked_load(mut slice: &[u8]) -> Self {
8676
let val0 = load_masked_opt(slice);
8777
slice = &slice[slice.len().min(16)..];
8878
if slice.is_empty() {
@@ -111,12 +101,10 @@ impl SimdInputTrait for SimdInput<16, 4> {
111101
}
112102

113103
#[inline]
114-
fn new_partial_copy(ptr: *const u8, len: usize) -> Self {
104+
fn new_partial_copy(slice: &[u8]) -> Self {
115105
let mut buf = [0; 64];
116-
unsafe {
117-
ptr.copy_to_nonoverlapping(buf.as_mut_ptr(), len);
118-
}
119-
Self::new(buf.as_ptr())
106+
buf[..slice.len()].copy_from_slice(slice);
107+
Self::new(&buf)
120108
}
121109

122110
#[inline]
@@ -128,7 +116,7 @@ impl SimdInputTrait for SimdInput<16, 4> {
128116
#[inline]
129117
fn load_masked_opt(slice: &[u8]) -> Simd<u8, 16> {
130118
if slice.len() > 15 {
131-
unsafe { slice.as_ptr().cast::<u8x16>().read_unaligned() }
119+
u8x16::from_slice(&slice[..16])
132120
} else {
133121
u8x16::load_or_default(slice)
134122
}
@@ -552,19 +540,15 @@ where
552540
// WORKAROUND
553541
// necessary because the for loop is not unrolled on ARM64
554542
if input.vals.len() == 2 {
555-
unsafe {
556-
self.check_bytes(*input.vals.as_ptr());
557-
self.check_bytes(*input.vals.as_ptr().add(1));
558-
self.incomplete = Self::is_incomplete(*input.vals.as_ptr().add(1));
559-
}
543+
self.check_bytes(input.vals[0]);
544+
self.check_bytes(input.vals[1]);
545+
self.incomplete = Self::is_incomplete(input.vals[1]);
560546
} else if input.vals.len() == 4 {
561-
unsafe {
562-
self.check_bytes(*input.vals.as_ptr());
563-
self.check_bytes(*input.vals.as_ptr().add(1));
564-
self.check_bytes(*input.vals.as_ptr().add(2));
565-
self.check_bytes(*input.vals.as_ptr().add(3));
566-
self.incomplete = Self::is_incomplete(*input.vals.as_ptr().add(3));
567-
}
547+
self.check_bytes(input.vals[0]);
548+
self.check_bytes(input.vals[1]);
549+
self.check_bytes(input.vals[2]);
550+
self.check_bytes(input.vals[3]);
551+
self.incomplete = Self::is_incomplete(input.vals[3]);
568552
} else {
569553
panic!("Unsupported number of chunks");
570554
}
@@ -578,28 +562,22 @@ where
578562
#[inline]
579563
pub fn validate_utf8_basic(input: &[u8]) -> core::result::Result<(), basic::Utf8Error> {
580564
use crate::implementation::helpers::SIMD_CHUNK_SIZE;
581-
let len = input.len();
582565
let mut algorithm = Self::new();
583-
let mut idx: usize = 0;
584-
let iter_lim = len - (len % SIMD_CHUNK_SIZE);
585-
586-
while idx < iter_lim {
587-
let simd_input = unsafe { SimdInput::<N, O>::new(input.as_ptr().add(idx)) };
588-
idx += SIMD_CHUNK_SIZE;
566+
let mut chunks = input.chunks_exact(SIMD_CHUNK_SIZE);
567+
for chunk in chunks.by_ref() {
568+
let simd_input = SimdInput::<N, O>::new(chunk);
589569
if !simd_input.is_ascii() {
590570
algorithm.check_block(&simd_input);
591571
break;
592572
}
593573
}
594-
595-
while idx < iter_lim {
596-
let input = unsafe { SimdInput::<N, O>::new(input.as_ptr().add(idx)) };
597-
algorithm.check_utf8(&input);
598-
idx += SIMD_CHUNK_SIZE;
574+
for chunk in chunks.by_ref() {
575+
let simd_input = SimdInput::<N, O>::new(chunk);
576+
algorithm.check_utf8(&simd_input);
599577
}
600-
601-
if idx < len {
602-
let simd_input = unsafe { SimdInput::new_partial(input.as_ptr().add(idx), len - idx) };
578+
let rem = chunks.remainder();
579+
if !rem.is_ascii() {
580+
let simd_input = SimdInput::<N, O>::new_partial(rem);
603581
algorithm.check_utf8(&simd_input);
604582
}
605583
algorithm.check_incomplete_pending();

0 commit comments

Comments
 (0)