@@ -12,7 +12,10 @@ use crate::string::String;
12
12
use crate :: table:: { Table , TablePairs } ;
13
13
use crate :: traits:: { FromLua , FromLuaMulti , IntoLua , IntoLuaMulti } ;
14
14
use crate :: types:: { MaybeSend , ValueRef } ;
15
- use crate :: util:: { check_stack, get_userdata, push_string, take_userdata, StackGuard } ;
15
+ use crate :: util:: {
16
+ borrow_userdata_scoped, borrow_userdata_scoped_mut, check_stack, get_userdata, push_string,
17
+ take_userdata, StackGuard , TypeIdHints ,
18
+ } ;
16
19
use crate :: value:: Value ;
17
20
18
21
#[ cfg( feature = "async" ) ]
26
29
27
30
// Re-export for convenience
28
31
pub ( crate ) use cell:: UserDataStorage ;
29
- pub use cell :: { UserDataRef , UserDataRefMut } ;
32
+ pub use r#ref :: { UserDataRef , UserDataRefMut } ;
30
33
pub use registry:: UserDataRegistry ;
31
34
pub ( crate ) use registry:: { RawUserDataRegistry , UserDataProxy } ;
32
35
@@ -622,7 +625,10 @@ impl AnyUserData {
622
625
/// Checks whether the type of this userdata is `T`.
623
626
#[ inline]
624
627
pub fn is < T : ' static > ( & self ) -> bool {
625
- self . inspect :: < T , _ , _ > ( |_| Ok ( ( ) ) ) . is_ok ( )
628
+ let lua = self . 0 . lua . lock ( ) ;
629
+ let type_id = lua. get_userdata_ref_type_id ( & self . 0 ) ;
630
+ // We do not use wrapped types here, rather prefer to check the "real" type of the userdata
631
+ matches ! ( type_id, Ok ( Some ( type_id) ) if type_id == TypeId :: of:: <T >( ) )
626
632
}
627
633
628
634
/// Borrow this userdata immutably if it is of type `T`.
@@ -637,15 +643,19 @@ impl AnyUserData {
637
643
/// [`DataTypeMismatch`]: crate::Error::UserDataTypeMismatch
638
644
#[ inline]
639
645
pub fn borrow < T : ' static > ( & self ) -> Result < UserDataRef < T > > {
640
- self . inspect ( |ud| ud. try_borrow_owned ( ) )
646
+ let lua = self . 0 . lua . lock ( ) ;
647
+ unsafe { UserDataRef :: borrow_from_stack ( & lua, lua. ref_thread ( ) , self . 0 . index ) }
641
648
}
642
649
643
650
/// Borrow this userdata immutably if it is of type `T`, passing the borrowed value
644
651
/// to the closure.
645
652
///
646
653
/// This method is the only way to borrow scoped userdata (created inside [`Lua::scope`]).
647
654
pub fn borrow_scoped < T : ' static , R > ( & self , f : impl FnOnce ( & T ) -> R ) -> Result < R > {
648
- self . inspect ( |ud| ud. try_borrow_scoped ( |ud| f ( ud) ) )
655
+ let lua = self . 0 . lua . lock ( ) ;
656
+ let type_id = lua. get_userdata_ref_type_id ( & self . 0 ) ?;
657
+ let type_hints = TypeIdHints :: new :: < T > ( ) ;
658
+ unsafe { borrow_userdata_scoped ( lua. ref_thread ( ) , self . 0 . index , type_id, type_hints, f) }
649
659
}
650
660
651
661
/// Borrow this userdata mutably if it is of type `T`.
@@ -660,15 +670,19 @@ impl AnyUserData {
660
670
/// [`UserDataTypeMismatch`]: crate::Error::UserDataTypeMismatch
661
671
#[ inline]
662
672
pub fn borrow_mut < T : ' static > ( & self ) -> Result < UserDataRefMut < T > > {
663
- self . inspect ( |ud| ud. try_borrow_owned_mut ( ) )
673
+ let lua = self . 0 . lua . lock ( ) ;
674
+ unsafe { UserDataRefMut :: borrow_from_stack ( & lua, lua. ref_thread ( ) , self . 0 . index ) }
664
675
}
665
676
666
677
/// Borrow this userdata mutably if it is of type `T`, passing the borrowed value
667
678
/// to the closure.
668
679
///
669
680
/// This method is the only way to borrow scoped userdata (created inside [`Lua::scope`]).
670
681
pub fn borrow_mut_scoped < T : ' static , R > ( & self , f : impl FnOnce ( & mut T ) -> R ) -> Result < R > {
671
- self . inspect ( |ud| ud. try_borrow_scoped_mut ( |ud| f ( ud) ) )
682
+ let lua = self . 0 . lua . lock ( ) ;
683
+ let type_id = lua. get_userdata_ref_type_id ( & self . 0 ) ?;
684
+ let type_hints = TypeIdHints :: new :: < T > ( ) ;
685
+ unsafe { borrow_userdata_scoped_mut ( lua. ref_thread ( ) , self . 0 . index , type_id, type_hints, f) }
672
686
}
673
687
674
688
/// Takes the value out of this userdata.
@@ -687,9 +701,11 @@ impl AnyUserData {
687
701
let type_id = lua. push_userdata_ref ( & self . 0 ) ?;
688
702
match type_id {
689
703
Some ( type_id) if type_id == TypeId :: of :: < T > ( ) => {
690
- // Try to borrow userdata exclusively
691
- let _ = ( * get_userdata :: < UserDataStorage < T > > ( state, -1 ) ) . try_borrow_mut ( ) ?;
692
- take_userdata :: < UserDataStorage < T > > ( state) . into_inner ( )
704
+ if ( * get_userdata :: < UserDataStorage < T > > ( state, -1 ) ) . has_exclusive_access ( ) {
705
+ take_userdata :: < UserDataStorage < T > > ( state) . into_inner ( )
706
+ } else {
707
+ Err ( Error :: UserDataBorrowMutError )
708
+ }
693
709
}
694
710
_ => Err ( Error :: UserDataTypeMismatch ) ,
695
711
}
@@ -965,24 +981,6 @@ impl AnyUserData {
965
981
} ;
966
982
is_serializable ( ) . unwrap_or ( false )
967
983
}
968
-
969
- pub ( crate ) fn inspect < T , F , R > ( & self , func : F ) -> Result < R >
970
- where
971
- T : ' static ,
972
- F : FnOnce ( & UserDataStorage < T > ) -> Result < R > ,
973
- {
974
- let lua = self . 0 . lua . lock ( ) ;
975
- unsafe {
976
- let type_id = lua. get_userdata_ref_type_id ( & self . 0 ) ?;
977
- match type_id {
978
- Some ( type_id) if type_id == TypeId :: of :: < T > ( ) => {
979
- let ud = get_userdata :: < UserDataStorage < T > > ( lua. ref_thread ( ) , self . 0 . index ) ;
980
- func ( & * ud)
981
- }
982
- _ => Err ( Error :: UserDataTypeMismatch ) ,
983
- }
984
- }
985
- }
986
984
}
987
985
988
986
/// Handle to a [`AnyUserData`] metatable.
@@ -1106,6 +1104,7 @@ where
1106
1104
mod cell;
1107
1105
mod lock;
1108
1106
mod object;
1107
+ mod r#ref;
1109
1108
mod registry;
1110
1109
mod util;
1111
1110
0 commit comments