88//! aren’t checked. See the [`high`](crate::high) layer for closures
99//! with type-checked arguments.
1010
11+ use crate :: low;
12+ pub use crate :: low:: { ffi_abi as FfiAbi , ffi_abi_FFI_DEFAULT_ABI, Callback , CallbackMut , CodePtr } ;
1113use alloc:: boxed:: Box ;
1214use core:: any:: Any ;
1315use core:: ffi:: c_void;
1416use core:: marker:: PhantomData ;
15-
16- use crate :: low;
17- pub use crate :: low:: { ffi_abi as FfiAbi , ffi_abi_FFI_DEFAULT_ABI, Callback , CallbackMut , CodePtr } ;
17+ use core:: ptr:: NonNull ;
1818
1919mod util;
2020
@@ -24,6 +24,17 @@ pub use types::Type;
2424mod builder;
2525pub use builder:: Builder ;
2626
27+ #[ derive( Debug ) ]
28+ pub ( crate ) struct ClosureAlloc ( NonNull < low:: ffi_closure > ) ;
29+
30+ impl Drop for ClosureAlloc {
31+ fn drop ( & mut self ) {
32+ unsafe {
33+ low:: closure_free ( self . 0 . as_ptr ( ) ) ;
34+ }
35+ }
36+ }
37+
2738/// Contains an untyped pointer to a function argument.
2839///
2940/// When calling a function via a [CIF](Cif), each argument
@@ -50,7 +61,7 @@ impl<'arg> Arg<'arg> {
5061///
5162/// This is used to wrap each argument pointer before passing them
5263/// to [`Cif::call`]. (This is the same as [`Arg::new`]).
53- pub fn arg < T : ?Sized > ( r : & T ) -> Arg {
64+ pub fn arg < T : ?Sized > ( r : & T ) -> Arg < ' _ > {
5465 Arg :: new ( r)
5566}
5667
@@ -277,19 +288,11 @@ impl Cif {
277288#[ derive( Debug ) ]
278289pub struct Closure < ' a > {
279290 _cif : Box < Cif > ,
280- alloc : * mut low :: ffi_closure ,
291+ _alloc : ClosureAlloc ,
281292 code : CodePtr ,
282293 _marker : PhantomData < & ' a ( ) > ,
283294}
284295
285- impl Drop for Closure < ' _ > {
286- fn drop ( & mut self ) {
287- unsafe {
288- low:: closure_free ( self . alloc ) ;
289- }
290- }
291- }
292-
293296impl < ' a > Closure < ' a > {
294297 /// Creates a new closure with immutable userdata.
295298 ///
@@ -307,10 +310,11 @@ impl<'a> Closure<'a> {
307310 pub fn new < U , R > ( cif : Cif , callback : Callback < U , R > , userdata : & ' a U ) -> Self {
308311 let cif = Box :: new ( cif) ;
309312 let ( alloc, code) = low:: closure_alloc ( ) ;
313+ let alloc = ClosureAlloc ( NonNull :: new ( alloc) . unwrap ( ) ) ;
310314
311315 unsafe {
312316 low:: prep_closure (
313- alloc,
317+ alloc. 0 . as_ptr ( ) ,
314318 cif. as_raw_ptr ( ) ,
315319 callback,
316320 userdata as * const U ,
@@ -321,7 +325,7 @@ impl<'a> Closure<'a> {
321325
322326 Closure {
323327 _cif : cif,
324- alloc,
328+ _alloc : alloc,
325329 code,
326330 _marker : PhantomData ,
327331 }
@@ -343,15 +347,22 @@ impl<'a> Closure<'a> {
343347 pub fn new_mut < U , R > ( cif : Cif , callback : CallbackMut < U , R > , userdata : & ' a mut U ) -> Self {
344348 let cif = Box :: new ( cif) ;
345349 let ( alloc, code) = low:: closure_alloc ( ) ;
350+ let alloc = ClosureAlloc ( NonNull :: new ( alloc) . unwrap ( ) ) ;
346351
347352 unsafe {
348- low:: prep_closure_mut ( alloc, cif. as_raw_ptr ( ) , callback, userdata as * mut U , code)
349- . unwrap ( ) ;
353+ low:: prep_closure_mut (
354+ alloc. 0 . as_ptr ( ) ,
355+ cif. as_raw_ptr ( ) ,
356+ callback,
357+ userdata as * mut U ,
358+ code,
359+ )
360+ . unwrap ( ) ;
350361 }
351362
352363 Closure {
353364 _cif : cif,
354- alloc,
365+ _alloc : alloc,
355366 code,
356367 _marker : PhantomData ,
357368 }
@@ -391,20 +402,12 @@ pub type CallbackOnce<U, R> = CallbackMut<Option<U>, R>;
391402/// which case the userdata will be gone if called again.
392403#[ derive( Debug ) ]
393404pub struct ClosureOnce {
394- alloc : * mut low :: ffi_closure ,
405+ _alloc : ClosureAlloc ,
395406 code : CodePtr ,
396407 _cif : Box < Cif > ,
397408 _userdata : Box < dyn Any > ,
398409}
399410
400- impl Drop for ClosureOnce {
401- fn drop ( & mut self ) {
402- unsafe {
403- low:: closure_free ( self . alloc ) ;
404- }
405- }
406- }
407-
408411impl ClosureOnce {
409412 /// Creates a new closure with owned userdata.
410413 ///
@@ -423,14 +426,13 @@ impl ClosureOnce {
423426 let _cif = Box :: new ( cif) ;
424427 let _userdata = Box :: new ( Some ( userdata) ) as Box < dyn Any > ;
425428 let ( alloc, code) = low:: closure_alloc ( ) ;
426-
427- assert ! ( !alloc. is_null( ) , "closure_alloc: returned null" ) ;
429+ let alloc = ClosureAlloc ( NonNull :: new ( alloc) . unwrap ( ) ) ;
428430
429431 {
430432 let borrow = _userdata. downcast_ref :: < Option < U > > ( ) . unwrap ( ) ;
431433 unsafe {
432434 low:: prep_closure_mut (
433- alloc,
435+ alloc. 0 . as_ptr ( ) ,
434436 _cif. as_raw_ptr ( ) ,
435437 callback,
436438 borrow as * const _ as * mut _ ,
@@ -441,7 +443,7 @@ impl ClosureOnce {
441443 }
442444
443445 ClosureOnce {
444- alloc,
446+ _alloc : alloc,
445447 code,
446448 _cif,
447449 _userdata,
0 commit comments