diff --git a/src/userdata/registry.rs b/src/userdata/registry.rs index 147f679..3c92ca8 100644 --- a/src/userdata/registry.rs +++ b/src/userdata/registry.rs @@ -5,7 +5,6 @@ use std::cell::RefCell; use std::marker::PhantomData; use std::os::raw::c_int; use std::string::String as StdString; -use std::sync::{Arc, Mutex, RwLock}; use crate::error::{Error, Result}; use crate::lua::Lua; @@ -74,61 +73,22 @@ impl<'a, T: 'static> UserDataRegistry<'a, T> { }; } - Box::new(move |lua, nargs| unsafe { + Box::new(move |rawlua, nargs| unsafe { if nargs == 0 { let err = Error::from_lua_conversion("missing argument", "userdata", None); try_self_arg!(Err(err)); } - let state = lua.state(); + let state = rawlua.state(); // Find absolute "self" index before processing args let index = ffi::lua_absindex(state, -nargs); // Self was at position 1, so we pass 2 here - let args = A::from_stack_args(nargs - 1, 2, Some(&name), lua); + let args = A::from_stack_args(nargs - 1, 2, Some(&name), rawlua); - match try_self_arg!(lua.get_userdata_type_id(index)) { + match try_self_arg!(rawlua.get_userdata_type_id(index)) { Some(id) if id == TypeId::of::() => { let ud = try_self_arg!(borrow_userdata_ref::(state, index)); - method(lua.lua(), &ud, args?)?.push_into_stack_multi(lua) + method(rawlua.lua(), &ud, args?)?.push_into_stack_multi(rawlua) } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>() => { - // let ud = try_self_arg!(get_userdata_ref::>(state, index)); - // method(lua.lua(), ud, args?)?.push_into_stack_multi(lua) - // } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(get_userdata_ref::>>(state, index)); - // let ud = try_self_arg!(ud.try_borrow(), Error::UserDataBorrowError); - // method(lua.lua(), &ud, args?)?.push_into_stack_multi(lua) - // } - // Some(id) if id == TypeId::of::>() => { - // let ud = try_self_arg!(get_userdata_ref::>(state, index)); - // method(lua.lua(), &ud, args?)?.push_into_stack_multi(lua) - // } - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(get_userdata_ref::>>(state, index)); - // let ud = try_self_arg!(ud.try_lock(), Error::UserDataBorrowError); - // method(lua.lua(), &ud, args?)?.push_into_stack_multi(lua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = get_userdata_ref::>>(state, index); - // let ud = try_self_arg!(ud); - // let ud = try_self_arg!(ud.try_lock().ok_or(Error::UserDataBorrowError)); - // method(lua.lua(), &ud, args?)?.push_into_stack_multi(lua) - // } - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(get_userdata_ref::>>(state, index)); - // let ud = try_self_arg!(ud.try_read(), Error::UserDataBorrowError); - // method(lua.lua(), &ud, args?)?.push_into_stack_multi(lua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = get_userdata_ref::>>(state, index); - // let ud = try_self_arg!(ud); - // let ud = try_self_arg!(ud.try_read().ok_or(Error::UserDataBorrowError)); - // method(lua.lua(), &ud, args?)?.push_into_stack_multi(lua) - // } _ => Err(Error::bad_self_argument(&name, Error::UserDataTypeMismatch)), } }) @@ -151,7 +111,7 @@ impl<'a, T: 'static> UserDataRegistry<'a, T> { } let method = RefCell::new(method); - Box::new(move |lua, nargs| unsafe { + Box::new(move |rawlua, nargs| unsafe { let mut method = method .try_borrow_mut() .map_err(|_| Error::RecursiveMutCallback)?; @@ -159,65 +119,32 @@ impl<'a, T: 'static> UserDataRegistry<'a, T> { let err = Error::from_lua_conversion("missing argument", "userdata", None); try_self_arg!(Err(err)); } - let state = lua.state(); + let state = rawlua.state(); // Find absolute "self" index before processing args let index = ffi::lua_absindex(state, -nargs); // Self was at position 1, so we pass 2 here - let args = A::from_stack_args(nargs - 1, 2, Some(&name), lua); + let args = A::from_stack_args(nargs - 1, 2, Some(&name), rawlua); - match try_self_arg!(lua.get_userdata_type_id(index)) { + match try_self_arg!(rawlua.get_userdata_type_id(index)) { Some(id) if id == TypeId::of::() => { let mut ud = try_self_arg!(borrow_userdata_mut::(state, index)); - method(lua.lua(), &mut ud, args?)?.push_into_stack_multi(lua) + method(rawlua.lua(), &mut ud, args?)?.push_into_stack_multi(rawlua) } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>() => Err(Error::UserDataBorrowMutError), - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(get_userdata_mut::>>(state, index)); - // let mut ud = try_self_arg!(ud.try_borrow_mut(), Error::UserDataBorrowMutError); - // method(lua.lua(), &mut ud, args?)?.push_into_stack_multi(lua) - // } - // Some(id) if id == TypeId::of::>() => Err(Error::UserDataBorrowMutError), - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(get_userdata_mut::>>(state, index)); - // let mut ud = try_self_arg!(ud.try_lock(), Error::UserDataBorrowMutError); - // method(lua.lua(), &mut ud, args?)?.push_into_stack_multi(lua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = get_userdata_mut::>>(state, index); - // let ud = try_self_arg!(ud); - // let mut ud = try_self_arg!(ud.try_lock().ok_or(Error::UserDataBorrowMutError)); - // method(lua.lua(), &mut ud, args?)?.push_into_stack_multi(lua) - // } - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(get_userdata_mut::>>(state, index)); - // let mut ud = try_self_arg!(ud.try_write(), Error::UserDataBorrowMutError); - // method(lua.lua(), &mut ud, args?)?.push_into_stack_multi(lua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = get_userdata_mut::>>(state, index); - // let ud = try_self_arg!(ud); - // let mut ud = try_self_arg!(ud.try_write().ok_or(Error::UserDataBorrowMutError)); - // method(lua.lua(), &mut ud, args?)?.push_into_stack_multi(lua) - // } _ => Err(Error::bad_self_argument(&name, Error::UserDataTypeMismatch)), } }) } #[cfg(feature = "async")] - fn box_async_method(name: String, method: M) -> AsyncCallback<'a> + fn box_async_method(name: &str, method: M) -> AsyncCallback<'a> where M: Fn(&'a Lua, &'a T, A) -> MR + MaybeSend + 'static, A: FromLuaMulti, MR: Future> + 'a, R: IntoLuaMulti, { - let name = Arc::new(get_function_name::(&name)); - let method = Arc::new(method); + let name = Rc::new(get_function_name::(name)); + let method = Rc::new(method); Box::new(move |rawlua, mut args| unsafe { let name = name.clone(); @@ -246,52 +173,6 @@ impl<'a, T: 'static> UserDataRegistry<'a, T> { let ud = std::mem::transmute::<&T, &T>(&ud); method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>() => { - // let ud = try_self_arg!(rawlua.get_userdata_ref::>(&this)); - // let ud = std::mem::transmute::<&T, &T>(&ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(rawlua.get_userdata_ref::>>(&this)); - // let ud = try_self_arg!(ud.try_borrow(), Error::UserDataBorrowError); - // let ud = std::mem::transmute::<&T, &T>(&ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // Some(id) if id == TypeId::of::>() => { - // let ud = try_self_arg!(rawlua.get_userdata_ref::>(&this)); - // let ud = std::mem::transmute::<&T, &T>(&ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(rawlua.get_userdata_ref::>>(&this)); - // let ud = try_self_arg!(ud.try_lock(), Error::UserDataBorrowError); - // let ud = std::mem::transmute::<&T, &T>(&ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = rawlua.get_userdata_ref::>>(&this); - // let ud = try_self_arg!(ud); - // let ud = try_self_arg!(ud.try_lock().ok_or(Error::UserDataBorrowError)); - // let ud = std::mem::transmute::<&T, &T>(&ud); - // method(lua, ud, args?).await?.push_into_stack_multi(lua) - // } - // Some(id) if id == TypeId::of::>>() => { - // let ud = try_self_arg!(rawlua.get_userdata_ref::>>(&this)); - // let ud = try_self_arg!(ud.try_read(), Error::UserDataBorrowError); - // let ud = std::mem::transmute::<&T, &T>(&ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = get_userdata_ref::>>(ref_thread, index); - // let ud = try_self_arg!(ud); - // let ud = try_self_arg!(ud.try_read().ok_or(Error::UserDataBorrowError)); - // let ud = std::mem::transmute::<&T, &T>(&ud); - // method(lua, ud, args?).await?.push_into_stack_multi(lua) - // } _ => Err(Error::bad_self_argument(&name, Error::UserDataTypeMismatch)), } }) @@ -299,15 +180,15 @@ impl<'a, T: 'static> UserDataRegistry<'a, T> { } #[cfg(feature = "async")] - fn box_async_method_mut(name: String, method: M) -> AsyncCallback<'a> + fn box_async_method_mut(name: &str, method: M) -> AsyncCallback<'a> where M: Fn(&'a Lua, &'a mut T, A) -> MR + MaybeSend + 'static, A: FromLuaMulti, MR: Future> + 'a, R: IntoLuaMulti, { - let name = Arc::new(get_function_name::(&name)); - let method = Arc::new(method); + let name = Rc::new(get_function_name::(name)); + let method = Rc::new(method); Box::new(move |rawlua, mut args| unsafe { let name = name.clone(); @@ -336,53 +217,6 @@ impl<'a, T: 'static> UserDataRegistry<'a, T> { let ud = std::mem::transmute::<&mut T, &mut T>(&mut ud); method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>>() => { - // Err(Error::UserDataBorrowMutError) - // } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>>() => { - // let ud = - // try_self_arg!(get_userdata_mut::>>(ref_thread, index)); - // let mut ud = - // try_self_arg!(ud.try_borrow_mut(), Error::UserDataBorrowMutError); - // let ud = std::mem::transmute::<&mut T, &mut T>(&mut ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // #[cfg(not(feature = "send"))] - // Some(id) if id == TypeId::of::>() => Err(Error::UserDataBorrowMutError), - // Some(id) if id == TypeId::of::>>() => { - // let ud = - // try_self_arg!(get_userdata_mut::>>(ref_thread, index)); - // let mut ud = try_self_arg!(ud.try_lock(), Error::UserDataBorrowMutError); - // let ud = std::mem::transmute::<&mut T, &mut T>(&mut ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = get_userdata_mut::>>(ref_thread, index); - // let ud = try_self_arg!(ud); - // let mut ud = - // try_self_arg!(ud.try_lock().ok_or(Error::UserDataBorrowMutError)); - // let ud = std::mem::transmute::<&mut T, &mut T>(&mut ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // Some(id) if id == TypeId::of::>>() => { - // let ud = - // try_self_arg!(get_userdata_mut::>>(ref_thread, index)); - // let mut ud = try_self_arg!(ud.try_write(), Error::UserDataBorrowMutError); - // let ud = std::mem::transmute::<&mut T, &mut T>(&mut ud); - // method(lua, ud, args?).await?.push_into_stack_multi(&rawlua) - // } - // #[cfg(feature = "parking_lot")] - // Some(id) if id == TypeId::of::>>() => { - // let ud = get_userdata_mut::>>(ref_thread, index); - // let ud = try_self_arg!(ud); - // let mut ud = - // try_self_arg!(ud.try_write().ok_or(Error::UserDataBorrowMutError)); - // let ud = std::mem::transmute::<&mut T, &mut T>(&mut ud); - // method(lua, ud, args?).await?.push_into_stack_multi(lua) - // } _ => Err(Error::bad_self_argument(&name, Error::UserDataTypeMismatch)), } }) @@ -420,7 +254,7 @@ impl<'a, T: 'static> UserDataRegistry<'a, T> { } #[cfg(feature = "async")] - fn box_async_function(name: String, function: F) -> AsyncCallback<'a> + fn box_async_function(name: &str, function: F) -> AsyncCallback<'a> where F: Fn(&'a Lua, A) -> FR + MaybeSend + 'static, A: FromLuaMulti, @@ -580,7 +414,7 @@ impl<'a, T: 'static> UserDataMethods<'a, T> for UserDataRegistry<'a, T> { R: IntoLuaMulti, { let name = name.to_string(); - let callback = Self::box_async_method(name.clone(), method); + let callback = Self::box_async_method(&name, method); self.async_methods.push((name, callback)); } @@ -593,7 +427,7 @@ impl<'a, T: 'static> UserDataMethods<'a, T> for UserDataRegistry<'a, T> { R: IntoLuaMulti, { let name = name.to_string(); - let callback = Self::box_async_method_mut(name.clone(), method); + let callback = Self::box_async_method_mut(&name, method); self.async_methods.push((name, callback)); } @@ -628,7 +462,7 @@ impl<'a, T: 'static> UserDataMethods<'a, T> for UserDataRegistry<'a, T> { R: IntoLuaMulti, { let name = name.to_string(); - let callback = Self::box_async_function(name.clone(), function); + let callback = Self::box_async_function(&name, function); self.async_methods.push((name, callback)); } @@ -663,7 +497,7 @@ impl<'a, T: 'static> UserDataMethods<'a, T> for UserDataRegistry<'a, T> { R: IntoLuaMulti, { let name = name.to_string(); - let callback = Self::box_async_method(name.clone(), method); + let callback = Self::box_async_method(&name, method); self.async_meta_methods.push((name, callback)); } @@ -676,7 +510,7 @@ impl<'a, T: 'static> UserDataMethods<'a, T> for UserDataRegistry<'a, T> { R: IntoLuaMulti, { let name = name.to_string(); - let callback = Self::box_async_method_mut(name.clone(), method); + let callback = Self::box_async_method_mut(&name, method); self.async_meta_methods.push((name, callback)); } @@ -711,13 +545,13 @@ impl<'a, T: 'static> UserDataMethods<'a, T> for UserDataRegistry<'a, T> { R: IntoLuaMulti, { let name = name.to_string(); - let callback = Self::box_async_function(name.clone(), function); + let callback = Self::box_async_function(&name, function); self.async_meta_methods.push((name, callback)); } } // Borrow the userdata in-place from the Lua stack -#[inline] +#[inline(always)] unsafe fn borrow_userdata_ref<'a, T>( state: *mut ffi::lua_State, index: c_int, @@ -727,7 +561,7 @@ unsafe fn borrow_userdata_ref<'a, T>( } // Borrow the userdata mutably in-place from the Lua stack -#[inline] +#[inline(always)] unsafe fn borrow_userdata_mut<'a, T>( state: *mut ffi::lua_State, index: c_int, @@ -761,19 +595,6 @@ macro_rules! lua_userdata_impl { }; } -#[cfg(not(feature = "send"))] -lua_userdata_impl!(Rc); -#[cfg(not(feature = "send"))] -lua_userdata_impl!(Rc>); - -lua_userdata_impl!(Arc); -lua_userdata_impl!(Arc>); -lua_userdata_impl!(Arc>); -#[cfg(feature = "parking_lot")] -lua_userdata_impl!(Arc>); -#[cfg(feature = "parking_lot")] -lua_userdata_impl!(Arc>); - // A special proxy object for UserData pub(crate) struct UserDataProxy(pub(crate) PhantomData); diff --git a/tests/userdata.rs b/tests/userdata.rs index 8d5acc6..ac026f9 100644 --- a/tests/userdata.rs +++ b/tests/userdata.rs @@ -1,10 +1,6 @@ use std::collections::HashMap; use std::string::String as StdString; use std::sync::Arc; -use std::sync::{Mutex, RwLock}; - -#[cfg(not(feature = "send"))] -use std::{cell::RefCell, rc::Rc}; #[cfg(feature = "lua54")] use std::sync::atomic::{AtomicI64, Ordering}; @@ -666,120 +662,6 @@ fn test_metatable() -> Result<()> { Ok(()) } -#[test] -#[ignore = "this functionality is deprecated"] -fn test_userdata_wrapped() -> Result<()> { - struct MyUserData(i64); - - impl UserData for MyUserData { - fn add_fields<'a, F: UserDataFields<'a, Self>>(fields: &mut F) { - fields.add_field("static", "constant"); - fields.add_field_method_get("data", |_, this| Ok(this.0)); - fields.add_field_method_set("data", |_, this, val| { - this.0 = val; - Ok(()) - }) - } - } - - let lua = Lua::new(); - let globals = lua.globals(); - - // Rc - #[cfg(not(feature = "send"))] - { - let ud = Rc::new(MyUserData(1)); - globals.set("rc_ud", ud.clone())?; - lua.load( - r#" - assert(rc_ud.static == "constant") - local ok, err = pcall(function() rc_ud.data = 2 end) - assert( - tostring(err):sub(1, 32) == "error mutably borrowing userdata", - "expected error mutably borrowing userdata, got " .. tostring(err) - ) - assert(rc_ud.data == 1) - "#, - ) - .exec()?; - globals.set("rc_ud", Nil)?; - lua.gc_collect()?; - assert_eq!(Rc::strong_count(&ud), 1); - } - - // Rc> - #[cfg(not(feature = "send"))] - { - let ud = Rc::new(RefCell::new(MyUserData(1))); - globals.set("rc_refcell_ud", ud.clone())?; - lua.load( - r#" - assert(rc_refcell_ud.static == "constant") - rc_refcell_ud.data = rc_refcell_ud.data + 1 - assert(rc_refcell_ud.data == 2) - "#, - ) - .exec()?; - assert_eq!(ud.borrow().0, 2); - globals.set("rc_refcell_ud", Nil)?; - lua.gc_collect()?; - assert_eq!(Rc::strong_count(&ud), 1); - } - - // Arc - let ud1 = Arc::new(MyUserData(2)); - globals.set("arc_ud", ud1.clone())?; - lua.load( - r#" - assert(arc_ud.static == "constant") - local ok, err = pcall(function() arc_ud.data = 3 end) - assert( - tostring(err):sub(1, 32) == "error mutably borrowing userdata", - "expected error mutably borrowing userdata, got " .. tostring(err) - ) - assert(arc_ud.data == 2) - "#, - ) - .exec()?; - globals.set("arc_ud", Nil)?; - lua.gc_collect()?; - assert_eq!(Arc::strong_count(&ud1), 1); - - // Arc> - let ud2 = Arc::new(Mutex::new(MyUserData(2))); - globals.set("arc_mutex_ud", ud2.clone())?; - lua.load( - r#" - assert(arc_mutex_ud.static == "constant") - arc_mutex_ud.data = arc_mutex_ud.data + 1 - assert(arc_mutex_ud.data == 3) - "#, - ) - .exec()?; - assert_eq!(ud2.lock().unwrap().0, 3); - globals.set("arc_mutex_ud", Nil)?; - lua.gc_collect()?; - assert_eq!(Arc::strong_count(&ud2), 1); - - // Arc> - let ud3 = Arc::new(RwLock::new(MyUserData(3))); - globals.set("arc_rwlock_ud", ud3.clone())?; - lua.load( - r#" - assert(arc_rwlock_ud.static == "constant") - arc_rwlock_ud.data = arc_rwlock_ud.data + 1 - assert(arc_rwlock_ud.data == 4) - "#, - ) - .exec()?; - assert_eq!(ud3.read().unwrap().0, 4); - globals.set("arc_rwlock_ud", Nil)?; - lua.gc_collect()?; - assert_eq!(Arc::strong_count(&ud3), 1); - - Ok(()) -} - #[test] fn test_userdata_proxy() -> Result<()> { struct MyUserData(i64);