@@ -20,7 +20,7 @@ use crate::types::{
2020 AppDataRef , AppDataRefMut , Callback , CallbackUpvalue , DestructedUserdata , Integer , LightUserData ,
2121 MaybeSend , ReentrantMutex , RegistryKey , SubtypeId , ValueRef , XRc ,
2222} ;
23- use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataRegistry , UserDataVariant } ;
23+ use crate :: userdata:: { AnyUserData , MetaMethod , UserData , UserDataRegistry , UserDataStorage } ;
2424use crate :: util:: {
2525 assert_stack, check_stack, get_destructed_userdata_metatable, get_internal_userdata, get_main_state,
2626 get_userdata, init_error_registry, init_internal_metatable, init_userdata_metatable, pop_error,
@@ -711,45 +711,45 @@ impl RawLua {
711711 }
712712 }
713713
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 >
715715 where
716716 T : UserData + ' static ,
717717 {
718718 self . make_userdata_with_metatable ( data, || {
719719 // Check if userdata/metatable is already registered
720720 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) {
722722 return Ok ( table_id as Integer ) ;
723723 }
724724
725725 // Create a new metatable from `UserData` definition
726- let mut registry = const { UserDataRegistry :: new ( ) } ;
726+ let mut registry = UserDataRegistry :: new ( type_id ) ;
727727 T :: register ( & mut registry) ;
728728
729- self . register_userdata_metatable ( registry)
729+ self . create_userdata_metatable ( registry)
730730 } )
731731 }
732732
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 >
734734 where
735735 T : ' static ,
736736 {
737737 self . make_userdata_with_metatable ( data, || {
738738 // Check if userdata/metatable is already registered
739739 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) {
741741 return Ok ( table_id as Integer ) ;
742742 }
743743
744744 // 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)
747747 } )
748748 }
749749
750750 unsafe fn make_userdata_with_metatable < T > (
751751 & self ,
752- data : UserDataVariant < T > ,
752+ data : UserDataStorage < T > ,
753753 get_metatable_id : impl FnOnce ( ) -> Result < Integer > ,
754754 ) -> Result < AnyUserData > {
755755 let state = self . state ( ) ;
@@ -760,10 +760,7 @@ impl RawLua {
760760 ffi:: lua_pushnil ( state) ;
761761 ffi:: lua_rawgeti ( state, ffi:: LUA_REGISTRYINDEX , get_metatable_id ( ) ?) ;
762762 let protect = !self . unlikely_memory_error ( ) ;
763- #[ cfg( not( feature = "lua54" ) ) ]
764763 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) ?;
767764 ffi:: lua_replace ( state, -3 ) ;
768765 ffi:: lua_setmetatable ( state, -2 ) ;
769766
@@ -782,12 +779,31 @@ impl RawLua {
782779 Ok ( AnyUserData ( self . pop_ref ( ) , SubtypeId :: None ) )
783780 }
784781
785- pub ( crate ) unsafe fn register_userdata_metatable < T : ' static > (
782+ pub ( crate ) unsafe fn create_userdata_metatable < T > (
786783 & self ,
787- mut registry : UserDataRegistry < T > ,
784+ registry : UserDataRegistry < T > ,
788785 ) -> Result < Integer > {
789786 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 ) ;
791807 check_stack ( state, 13 ) ?;
792808
793809 // Prepare metatable, add meta methods first and then meta fields
@@ -922,7 +938,7 @@ impl RawLua {
922938 let extra_init = None ;
923939 #[ cfg( not( feature = "luau" ) ) ]
924940 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 > > ) ;
926942 rawset_field ( state, -2 , "__gc" )
927943 } ) ;
928944
@@ -938,44 +954,21 @@ impl RawLua {
938954 // Pop extra tables to get metatable on top of the stack
939955 ffi:: lua_pop ( state, extra_tables_count) ;
940956
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+ }
951959
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) ;
953963 }
954964
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+ }
979972
980973 // Returns `TypeId` for the userdata ref, checking that it's registered and not destructed.
981974 //
@@ -1028,17 +1021,17 @@ impl RawLua {
10281021
10291022 // Creates a Function out of a Callback containing a 'static Fn.
10301023 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
10331024 unsafe extern "C-unwind" fn call_callback ( state : * mut ffi:: lua_State ) -> c_int {
10341025 let upvalue = get_userdata :: < CallbackUpvalue > ( state, ffi:: lua_upvalueindex ( 1 ) ) ;
10351026 callback_error_ext ( state, ( * upvalue) . extra . get ( ) , |extra, nargs| {
10361027 // Lua ensures that `LUA_MINSTACK` stack spaces are available (after pushing arguments)
10371028 // The lock must be already held as the callback is executed
10381029 let rawlua = ( * extra) . raw_lua ( ) ;
10391030 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+ }
10421035 } )
10431036 }
10441037
@@ -1047,6 +1040,7 @@ impl RawLua {
10471040 let _sg = StackGuard :: new ( state) ;
10481041 check_stack ( state, 4 ) ?;
10491042
1043+ let func = Some ( func) ;
10501044 let extra = XRc :: clone ( & self . extra ) ;
10511045 let protect = !self . unlikely_memory_error ( ) ;
10521046 push_internal_userdata ( state, CallbackUpvalue { data : func, extra } , protect) ?;
0 commit comments