summaryrefslogtreecommitdiff
path: root/src/util.rs
diff options
context:
space:
mode:
authorkyren <kerriganw@gmail.com>2017-10-14 18:26:09 -0400
committerkyren <kerriganw@gmail.com>2017-10-14 18:26:09 -0400
commit4b7a3403bc04a6f73cb105de6a97f32ad414e7cd (patch)
tree432ef39e0144d7b2d5dcb01b1f22a8d6fac3d70a /src/util.rs
parentc5a4dfd7ebed829109a320ae803cefb8d5168fc7 (diff)
downloadmlua-4b7a3403bc04a6f73cb105de6a97f32ad414e7cd.zip
Cleanups of userdata handling, particularly around callbacks
First, make sure that `add_methods` cannot trigger another userdata registry insert, causing an unintended panic. Second, remove `RefCell` surrounding userdata hashmap, as this change makes it no longer needed. Third, add a `RefCell` around `Callback` because FnMut means that callbacks cannot recurse into themselves, and panic appropriately when this happens. This should eventually be turned into an error.
Diffstat (limited to 'src/util.rs')
-rw-r--r--src/util.rs17
1 files changed, 8 insertions, 9 deletions
diff --git a/src/util.rs b/src/util.rs
index bce5166..8d03036 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -257,8 +257,8 @@ pub unsafe fn handle_error(state: *mut ffi::lua_State, err: c_int) -> Result<()>
Err(err)
} else if is_wrapped_panic(state, -1) {
- let panic = &mut *get_userdata::<WrappedPanic>(state, -1);
- if let Some(p) = panic.0.take() {
+ let panic = get_userdata::<WrappedPanic>(state, -1);
+ if let Some(p) = (*panic).0.take() {
ffi::lua_settop(state, 0);
resume_unwind(p);
} else {
@@ -317,17 +317,16 @@ pub unsafe fn push_string(state: *mut ffi::lua_State, s: &str) {
ffi::lua_pushlstring(state, s.as_ptr() as *const c_char, s.len());
}
-pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) -> *mut T {
+pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) {
let ud = ffi::lua_newuserdata(state, mem::size_of::<Option<T>>()) as *mut Option<T>;
- ptr::write(ud, None);
- *ud = Some(t);
- (*ud).as_mut().unwrap()
+ ptr::write(ud, Some(t));
}
pub unsafe fn get_userdata<T>(state: *mut ffi::lua_State, index: c_int) -> *mut T {
let ud = ffi::lua_touserdata(state, index) as *mut Option<T>;
lua_assert!(state, !ud.is_null());
- (*ud).as_mut().expect("access of expired userdata")
+ lua_assert!(state, (*ud).is_some(), "access of expired userdata");
+ (*ud).as_mut().unwrap()
}
pub unsafe extern "C" fn userdata_destructor<T>(state: *mut ffi::lua_State) -> c_int {
@@ -552,8 +551,8 @@ pub struct WrappedPanic(pub Option<Box<Any + Send>>);
pub unsafe fn push_wrapped_error(state: *mut ffi::lua_State, err: Error) {
unsafe extern "C" fn error_tostring(state: *mut ffi::lua_State) -> c_int {
callback_error(state, || if is_wrapped_error(state, -1) {
- let error = &*get_userdata::<WrappedError>(state, -1);
- push_string(state, &error.0.to_string());
+ let error = get_userdata::<WrappedError>(state, -1);
+ push_string(state, &(*error).0.to_string());
ffi::lua_remove(state, -2);
Ok(1)