diff --git a/Cargo.toml b/Cargo.toml index e695d1026..5ba302cca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,7 +115,7 @@ rev = "de226a26e8e18edbdb1d6f986afe37bbbf35fbf4" version = "0.0.0" edition = "2021" publish = false -rust-version = "1.81.0" +rust-version = "1.84.0" license = "MIT" # min-sized-rustを元にrelease buildのサイズが小さくなるようにした diff --git a/crates/voicevox_core/src/infer/runtimes/onnxruntime.rs b/crates/voicevox_core/src/infer/runtimes/onnxruntime.rs index 2f971cabc..093828f17 100644 --- a/crates/voicevox_core/src/infer/runtimes/onnxruntime.rs +++ b/crates/voicevox_core/src/infer/runtimes/onnxruntime.rs @@ -296,13 +296,11 @@ pub(crate) mod blocking { /// # .filename(test_util::ONNXRUNTIME_DYLIB_PATH) /// # .exec()?; /// # + /// use std::ptr; + /// /// let ort1 = voicevox_core::blocking::Onnxruntime::load_once().exec()?; /// let ort2 = another_lib::nonblocking::Onnxruntime::get().expect("`ort1`と同一のはず"); - /// assert_eq!(ptr_addr(ort1), ptr_addr(ort2)); - /// - /// fn ptr_addr(obj: &impl Sized) -> usize { - /// &raw const *obj as _ - /// } + /// assert!(ptr::addr_eq(ort1, ort2)); /// # Ok(()) /// # } /// ``` diff --git a/crates/voicevox_core_c_api/src/drop_check.rs b/crates/voicevox_core_c_api/src/drop_check.rs index 92fdd5ec0..209c85d16 100644 --- a/crates/voicevox_core_c_api/src/drop_check.rs +++ b/crates/voicevox_core_c_api/src/drop_check.rs @@ -1,9 +1,13 @@ use std::{ collections::BTreeSet, ffi::{c_char, CStr, CString}, + num::NonZero, + ptr::NonNull, sync::Mutex, }; +use easy_ext::ext; + /// dropして良い`*mut c_char`を把握し、チェックする。 /// /// `Mutex`による内部可変性を持ち、すべての操作は共有参照から行うことができる。 @@ -26,8 +30,8 @@ pub(crate) static C_STRING_DROP_CHECKER: CStringDropChecker = CStringDropChecker pub(crate) struct CStringDropChecker(Mutex); struct Inner { - owned_str_addrs: BTreeSet, - static_str_addrs: BTreeSet, + owned_str_addrs: BTreeSet>, + static_str_addrs: BTreeSet>, } impl CStringDropChecker { @@ -46,8 +50,8 @@ impl CStringDropChecker { owned_str_addrs, .. } = &mut *self.0.lock().unwrap(); - let ptr = s.as_ptr(); - let duplicated = !owned_str_addrs.insert(ptr as usize); + let ptr = s.as_non_null_ptr(); + let duplicated = !owned_str_addrs.insert(ptr.addr()); if duplicated { panic!( "別の{ptr:p}が管理下にあります。原因としては以前に別の文字列が{ptr:p}として存在\ @@ -69,7 +73,7 @@ impl CStringDropChecker { static_str_addrs, .. } = &mut *self.0.lock().unwrap(); - static_str_addrs.insert(s.as_ptr() as usize); + static_str_addrs.insert(s.as_non_null_ptr().addr()); s } @@ -85,7 +89,7 @@ impl CStringDropChecker { .. } = &mut *self.0.lock().unwrap(); - let addr = ptr as usize; + let addr = NonZero::new(ptr.addr()).expect("ヌルポインタは解放できません"); if !owned_str_addrs.remove(&addr) { if static_str_addrs.contains(&addr) { panic!( @@ -103,6 +107,13 @@ impl CStringDropChecker { } } +#[ext] +impl CStr { + fn as_non_null_ptr(&self) -> NonNull { + NonNull::new(self.as_ptr() as *mut c_char).expect("comes from a `CStr`") + } +} + #[cfg(test)] mod tests { use std::ffi::{c_char, CStr}; diff --git a/crates/voicevox_core_c_api/src/lib.rs b/crates/voicevox_core_c_api/src/lib.rs index 38d4706b6..45adec387 100644 --- a/crates/voicevox_core_c_api/src/lib.rs +++ b/crates/voicevox_core_c_api/src/lib.rs @@ -1071,7 +1071,7 @@ pub unsafe extern "C" fn voicevox_synthesizer_synthesis( style_id: VoicevoxStyleId, options: VoicevoxSynthesisOptions, output_wav_length: NonNull, - output_wav: NonNull<*mut u8>, + output_wav: NonNull>, ) -> VoicevoxResultCode { init_logger_once(); into_result_code_with_error((|| { @@ -1137,7 +1137,7 @@ pub unsafe extern "C" fn voicevox_synthesizer_tts_from_kana( style_id: VoicevoxStyleId, options: VoicevoxTtsOptions, output_wav_length: NonNull, - output_wav: NonNull<*mut u8>, + output_wav: NonNull>, ) -> VoicevoxResultCode { init_logger_once(); into_result_code_with_error((|| { @@ -1182,7 +1182,7 @@ pub unsafe extern "C" fn voicevox_synthesizer_tts( style_id: VoicevoxStyleId, options: VoicevoxTtsOptions, output_wav_length: NonNull, - output_wav: NonNull<*mut u8>, + output_wav: NonNull>, ) -> VoicevoxResultCode { init_logger_once(); into_result_code_with_error((|| { diff --git a/crates/voicevox_core_c_api/src/object.rs b/crates/voicevox_core_c_api/src/object.rs index 5cd6aa3df..21dad1159 100644 --- a/crates/voicevox_core_c_api/src/object.rs +++ b/crates/voicevox_core_c_api/src/object.rs @@ -64,9 +64,9 @@ pub(crate) trait CApiObject: Default + Debug + 'static { let i = Self::heads().push(Default::default()); NonNull::from(&Self::heads()[i]) }; - Self::lock_known_addrs().insert(this.addr_without_provenance()); + Self::lock_known_addrs().insert(this.addr()); let body = parking_lot::RwLock::new(body.into()).into(); - Self::lock_bodies().insert(this.addr_without_provenance(), body); + Self::lock_bodies().insert(this.addr(), body); this } } @@ -86,7 +86,7 @@ impl *const T { let this = self.validate(); let body = T::lock_bodies() - .get(&this.addr_without_provenance()) + .get(&this.addr()) .unwrap_or_else(|| this.panic_for_deleted()) .read_arc(); @@ -103,7 +103,7 @@ impl *const T { let this = self.validate(); let body = T::lock_bodies() - .remove(&this.addr_without_provenance()) + .remove(&this.addr()) .unwrap_or_else(|| this.panic_for_deleted()); drop( @@ -125,7 +125,7 @@ impl *const T { impl *const T { fn validate(self) -> NonNull { let this = NonNull::new(self as *mut T).expect("the argument must not be null"); - if !T::lock_known_addrs().contains(&this.addr_without_provenance()) { + if !T::lock_known_addrs().contains(&this.addr()) { panic!("{self:018p} does not seem to be valid object"); } this @@ -147,13 +147,6 @@ impl NonNull { } } -#[ext] -impl NonNull { - fn addr_without_provenance(self) -> NonZero { - NonZero::new(self.as_ptr() as _).expect("this is from `NonNull`") - } -} - #[ext] impl T { fn lock_known_addrs() -> impl DerefMut>> { diff --git a/crates/voicevox_core_c_api/src/slice_owner.rs b/crates/voicevox_core_c_api/src/slice_owner.rs index cedcd7417..68d3a50fc 100644 --- a/crates/voicevox_core_c_api/src/slice_owner.rs +++ b/crates/voicevox_core_c_api/src/slice_owner.rs @@ -1,4 +1,4 @@ -use std::{cell::UnsafeCell, collections::BTreeMap, ptr::NonNull, sync::Mutex}; +use std::{cell::UnsafeCell, collections::BTreeMap, num::NonZeroUsize, ptr::NonNull, sync::Mutex}; /// Cの世界に貸し出す`[u8]`の所有者(owner)。 /// @@ -16,7 +16,7 @@ use std::{cell::UnsafeCell, collections::BTreeMap, ptr::NonNull, sync::Mutex}; pub(crate) static U8_SLICE_OWNER: SliceOwner = SliceOwner::new(); pub(crate) struct SliceOwner { - slices: Mutex>>>, + slices: Mutex>>>, } impl SliceOwner { @@ -37,16 +37,16 @@ impl SliceOwner { pub(crate) unsafe fn own_and_lend( &self, slice: impl Into>, - out_ptr: NonNull<*mut T>, + out_ptr: NonNull>, out_len: NonNull, ) { let mut slices = self.slices.lock().unwrap(); let slice = slice.into(); - let ptr = slice.as_ptr() as *mut T; + let ptr = NonNull::new(slice.as_ptr() as *mut T).expect("comes from a slice"); let len = slice.len(); - let duplicated = slices.insert(ptr as usize, slice.into()).is_some(); + let duplicated = slices.insert(ptr.addr(), slice.into()).is_some(); if duplicated { panic!( "別の{ptr:p}が管理下にあります。原因としては以前に別の配列が{ptr:p}として存在\ @@ -67,10 +67,12 @@ impl SliceOwner { pub(crate) fn drop_for(&self, ptr: *mut T) { let mut slices = self.slices.lock().unwrap(); - slices.remove(&(ptr as usize)).expect( - "解放しようとしたポインタはvoicevox_coreの管理下にありません。\ - 誤ったポインタであるか、二重解放になっていることが考えられます", - ); + NonNull::new(ptr) + .and_then(|ptr| slices.remove(&ptr.addr())) + .expect( + "解放しようとしたポインタはvoicevox_coreの管理下にありません。\ + 誤ったポインタであるか、二重解放になっていることが考えられます", + ); } } @@ -108,7 +110,7 @@ mod tests { (ptr.assume_init(), len.assume_init()) }; assert_eq!(expected_len, len); - owner.drop_for(ptr); + owner.drop_for(ptr.as_ptr()); } fn vec(initial_cap: usize, elems: &[T]) -> Vec { diff --git a/rust-toolchain b/rust-toolchain index 6b4de0a42..bd0f9e6c2 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.83.0 +1.84.0