@@ -20,7 +20,7 @@ use crate::types::{
20
20
AppDataRef , AppDataRefMut , Callback , CallbackUpvalue , DestructedUserdata , Integer , LightUserData ,
21
21
MaybeSend , ReentrantMutex , RegistryKey , SubtypeId , ValueRef , XRc ,
22
22
} ;
23
- use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataRegistry , UserDataVariant } ;
23
+ use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataRegistry , UserDataStorage } ;
24
24
use crate :: util:: {
25
25
assert_stack, check_stack, get_destructed_userdata_metatable, get_internal_userdata, get_main_state,
26
26
get_userdata, init_error_registry, init_internal_metatable, init_userdata_metatable, pop_error,
@@ -711,45 +711,45 @@ impl RawLua {
711
711
}
712
712
}
713
713
714
- pub ( crate ) unsafe fn make_userdata < T > ( & self , data : UserDataVariant < T > ) -> Result < AnyUserData >
714
+ pub ( crate ) unsafe fn make_userdata < T > ( & self , data : UserDataStorage < T > ) -> Result < AnyUserData >
715
715
where
716
716
T : UserData + ' static ,
717
717
{
718
718
self . make_userdata_with_metatable ( data, || {
719
719
// Check if userdata/metatable is already registered
720
720
let type_id = TypeId :: of :: < T > ( ) ;
721
- if let Some ( & table_id) = ( * self . extra . get ( ) ) . registered_userdata . get ( & type_id) {
721
+ if let Some ( & table_id) = ( * self . extra . get ( ) ) . registered_userdata_t . get ( & type_id) {
722
722
return Ok ( table_id as Integer ) ;
723
723
}
724
724
725
725
// Create a new metatable from `UserData` definition
726
- let mut registry = const { UserDataRegistry :: new ( ) } ;
726
+ let mut registry = UserDataRegistry :: new ( type_id ) ;
727
727
T :: register ( & mut registry) ;
728
728
729
- self . register_userdata_metatable ( registry)
729
+ self . create_userdata_metatable ( registry)
730
730
} )
731
731
}
732
732
733
- pub ( crate ) unsafe fn make_any_userdata < T > ( & self , data : UserDataVariant < T > ) -> Result < AnyUserData >
733
+ pub ( crate ) unsafe fn make_any_userdata < T > ( & self , data : UserDataStorage < T > ) -> Result < AnyUserData >
734
734
where
735
735
T : ' static ,
736
736
{
737
737
self . make_userdata_with_metatable ( data, || {
738
738
// Check if userdata/metatable is already registered
739
739
let type_id = TypeId :: of :: < T > ( ) ;
740
- if let Some ( & table_id) = ( * self . extra . get ( ) ) . registered_userdata . get ( & type_id) {
740
+ if let Some ( & table_id) = ( * self . extra . get ( ) ) . registered_userdata_t . get ( & type_id) {
741
741
return Ok ( table_id as Integer ) ;
742
742
}
743
743
744
744
// Create an empty metatable
745
- let registry = const { UserDataRegistry :: new ( ) } ;
746
- self . register_userdata_metatable :: < T > ( registry)
745
+ let registry = UserDataRegistry :: < T > :: new ( type_id ) ;
746
+ self . create_userdata_metatable ( registry)
747
747
} )
748
748
}
749
749
750
750
unsafe fn make_userdata_with_metatable < T > (
751
751
& self ,
752
- data : UserDataVariant < T > ,
752
+ data : UserDataStorage < T > ,
753
753
get_metatable_id : impl FnOnce ( ) -> Result < Integer > ,
754
754
) -> Result < AnyUserData > {
755
755
let state = self . state ( ) ;
@@ -760,10 +760,7 @@ impl RawLua {
760
760
ffi:: lua_pushnil ( state) ;
761
761
ffi:: lua_rawgeti ( state, ffi:: LUA_REGISTRYINDEX , get_metatable_id ( ) ?) ;
762
762
let protect = !self . unlikely_memory_error ( ) ;
763
- #[ cfg( not( feature = "lua54" ) ) ]
764
763
crate :: util:: push_userdata ( state, data, protect) ?;
765
- #[ cfg( feature = "lua54" ) ]
766
- crate :: util:: push_userdata_uv ( state, data, crate :: userdata:: USER_VALUE_MAXSLOT as c_int , protect) ?;
767
764
ffi:: lua_replace ( state, -3 ) ;
768
765
ffi:: lua_setmetatable ( state, -2 ) ;
769
766
@@ -782,12 +779,31 @@ impl RawLua {
782
779
Ok ( AnyUserData ( self . pop_ref ( ) , SubtypeId :: None ) )
783
780
}
784
781
785
- pub ( crate ) unsafe fn register_userdata_metatable < T : ' static > (
782
+ pub ( crate ) unsafe fn create_userdata_metatable < T > (
786
783
& self ,
787
- mut registry : UserDataRegistry < T > ,
784
+ registry : UserDataRegistry < T > ,
788
785
) -> Result < Integer > {
789
786
let state = self . state ( ) ;
790
- let _sg = StackGuard :: new ( state) ;
787
+ let type_id = registry. type_id ( ) ;
788
+
789
+ self . push_userdata_metatable ( registry) ?;
790
+
791
+ let mt_ptr = ffi:: lua_topointer ( state, -1 ) ;
792
+ let id = protect_lua ! ( state, 1 , 0 , |state| {
793
+ ffi:: luaL_ref( state, ffi:: LUA_REGISTRYINDEX )
794
+ } ) ?;
795
+
796
+ if let Some ( type_id) = type_id {
797
+ ( * self . extra . get ( ) ) . registered_userdata_t . insert ( type_id, id) ;
798
+ }
799
+ self . register_userdata_metatable ( mt_ptr, type_id) ;
800
+
801
+ Ok ( id as Integer )
802
+ }
803
+
804
+ pub ( crate ) unsafe fn push_userdata_metatable < T > ( & self , mut registry : UserDataRegistry < T > ) -> Result < ( ) > {
805
+ let state = self . state ( ) ;
806
+ let _sg = StackGuard :: with_top ( state, ffi:: lua_gettop ( state) + 1 ) ;
791
807
check_stack ( state, 13 ) ?;
792
808
793
809
// Prepare metatable, add meta methods first and then meta fields
@@ -922,7 +938,7 @@ impl RawLua {
922
938
let extra_init = None ;
923
939
#[ cfg( not( feature = "luau" ) ) ]
924
940
let extra_init: Option < fn ( * mut ffi:: lua_State ) -> Result < ( ) > > = Some ( |state| {
925
- ffi:: lua_pushcfunction ( state, crate :: util:: userdata_destructor :: < UserDataVariant < T > > ) ;
941
+ ffi:: lua_pushcfunction ( state, crate :: util:: userdata_destructor :: < UserDataStorage < T > > ) ;
926
942
rawset_field ( state, -2 , "__gc" )
927
943
} ) ;
928
944
@@ -938,44 +954,21 @@ impl RawLua {
938
954
// Pop extra tables to get metatable on top of the stack
939
955
ffi:: lua_pop ( state, extra_tables_count) ;
940
956
941
- let mt_ptr = ffi:: lua_topointer ( state, -1 ) ;
942
- let id = protect_lua ! ( state, 1 , 0 , |state| {
943
- ffi:: luaL_ref( state, ffi:: LUA_REGISTRYINDEX )
944
- } ) ?;
945
-
946
- let type_id = TypeId :: of :: < T > ( ) ;
947
- ( * self . extra . get ( ) ) . registered_userdata . insert ( type_id, id) ;
948
- ( * self . extra . get ( ) )
949
- . registered_userdata_mt
950
- . insert ( mt_ptr, Some ( type_id) ) ;
957
+ Ok ( ( ) )
958
+ }
951
959
952
- Ok ( id as Integer )
960
+ #[ inline( always) ]
961
+ pub ( crate ) unsafe fn register_userdata_metatable ( & self , mt_ptr : * const c_void , type_id : Option < TypeId > ) {
962
+ ( * self . extra . get ( ) ) . registered_userdata_mt . insert ( mt_ptr, type_id) ;
953
963
}
954
964
955
- // #[inline]
956
- // pub(crate) unsafe fn register_raw_userdata_metatable(
957
- // &self,
958
- // ptr: *const c_void,
959
- // type_id: Option<TypeId>,
960
- // ) {
961
- // (*self.extra.get())
962
- // .registered_userdata_mt
963
- // .insert(ptr, type_id);
964
- // }
965
-
966
- // #[inline]
967
- // pub(crate) unsafe fn deregister_raw_userdata_metatable(&self, ptr: *const c_void) {
968
- // (*self.extra.get()).registered_userdata_mt.remove(&ptr);
969
- // if (*self.extra.get()).last_checked_userdata_mt.0 == ptr {
970
- // (*self.extra.get()).last_checked_userdata_mt = (ptr::null(), None);
971
- // }
972
- // }
973
-
974
- // #[inline(always)]
975
- // pub(crate) unsafe fn get_userdata_ref<T: 'static>(&self, idx: c_int) -> Result<UserDataRef<T>> {
976
- // let guard = self.lua().lock_arc();
977
- // (*get_userdata::<UserDataVariant<T>>(self.state(), idx)).try_make_ref(guard)
978
- // }
965
+ #[ inline( always) ]
966
+ pub ( crate ) unsafe fn deregister_userdata_metatable ( & self , mt_ptr : * const c_void ) {
967
+ ( * self . extra . get ( ) ) . registered_userdata_mt . remove ( & mt_ptr) ;
968
+ if ( * self . extra . get ( ) ) . last_checked_userdata_mt . 0 == mt_ptr {
969
+ ( * self . extra . get ( ) ) . last_checked_userdata_mt = ( ptr:: null ( ) , None ) ;
970
+ }
971
+ }
979
972
980
973
// Returns `TypeId` for the userdata ref, checking that it's registered and not destructed.
981
974
//
@@ -1028,17 +1021,17 @@ impl RawLua {
1028
1021
1029
1022
// Creates a Function out of a Callback containing a 'static Fn.
1030
1023
pub ( crate ) fn create_callback ( & self , func : Callback ) -> Result < Function > {
1031
- // This is non-scoped version of the callback (upvalue is always valid)
1032
- // TODO: add a scoped version
1033
1024
unsafe extern "C-unwind" fn call_callback ( state : * mut ffi:: lua_State ) -> c_int {
1034
1025
let upvalue = get_userdata :: < CallbackUpvalue > ( state, ffi:: lua_upvalueindex ( 1 ) ) ;
1035
1026
callback_error_ext ( state, ( * upvalue) . extra . get ( ) , |extra, nargs| {
1036
1027
// Lua ensures that `LUA_MINSTACK` stack spaces are available (after pushing arguments)
1037
1028
// The lock must be already held as the callback is executed
1038
1029
let rawlua = ( * extra) . raw_lua ( ) ;
1039
1030
let _guard = StateGuard :: new ( rawlua, state) ;
1040
- let func = & * ( * upvalue) . data ;
1041
- func ( rawlua, nargs)
1031
+ match ( * upvalue) . data {
1032
+ Some ( ref func) => func ( rawlua, nargs) ,
1033
+ None => Err ( Error :: CallbackDestructed ) ,
1034
+ }
1042
1035
} )
1043
1036
}
1044
1037
@@ -1047,6 +1040,7 @@ impl RawLua {
1047
1040
let _sg = StackGuard :: new ( state) ;
1048
1041
check_stack ( state, 4 ) ?;
1049
1042
1043
+ let func = Some ( func) ;
1050
1044
let extra = XRc :: clone ( & self . extra ) ;
1051
1045
let protect = !self . unlikely_memory_error ( ) ;
1052
1046
push_internal_userdata ( state, CallbackUpvalue { data : func, extra } , protect) ?;
0 commit comments