summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkyren <kerriganw@gmail.com>2017-12-16 17:44:13 -0500
committerkyren <kerriganw@gmail.com>2017-12-16 17:44:13 -0500
commitbfb6111e0a8ff7490fdc9a152565656dd3754ad9 (patch)
tree4ead0125637c4660a055a289c9737a883fcb5029 /src
parent56c9493f23b45eb0c2f2595c9f2dbf3573429554 (diff)
downloadmlua-bfb6111e0a8ff7490fdc9a152565656dd3754ad9.zip
API for registry access via string keys only (for now)
Also includes some fixes for stack usage and changes an assert_eq to lua_assert
Diffstat (limited to 'src')
-rw-r--r--src/lua.rs46
-rw-r--r--src/tests.rs13
-rw-r--r--src/util.rs2
3 files changed, 55 insertions, 6 deletions
diff --git a/src/lua.rs b/src/lua.rs
index 1a9d8ad..74bc76b 100644
--- a/src/lua.rs
+++ b/src/lua.rs
@@ -135,7 +135,7 @@ impl Lua {
pub fn create_string(&self, s: &str) -> Result<String> {
unsafe {
stack_err_guard(self.state, 0, || {
- check_stack(self.state, 2);
+ check_stack(self.state, 4);
push_string(self.state, s)?;
Ok(String(self.pop_ref(self.state)))
})
@@ -405,7 +405,41 @@ impl Lua {
T::from_lua_multi(value, self)
}
- // Used 1 stack space, does not call checkstack
+ /// Set a value in the Lua registry based on a string key.
+ ///
+ /// This value will be available to rust from all `Lua` instances which share the same main
+ /// state.
+ pub fn set_registry<'lua, T: ToLua<'lua>>(&'lua self, registry_key: &str, t: T) -> Result<()> {
+ unsafe {
+ stack_err_guard(self.state, 0, || {
+ check_stack(self.state, 5);
+ push_string(self.state, registry_key)?;
+ self.push_value(self.state, t.to_lua(self)?);
+ protect_lua_call(self.state, 2, 0, |state| {
+ ffi::lua_settable(state, ffi::LUA_REGISTRYINDEX);
+ })
+ })
+ }
+ }
+
+ /// Get a value from the Lua registry based on a string key.
+ ///
+ /// Any Lua instance which shares the underlying main state may call `get_registry` to get a
+ /// value previously set by `set_registry`.
+ pub fn get_registry<'lua, T: FromLua<'lua>>(&'lua self, registry_key: &str) -> Result<T> {
+ unsafe {
+ stack_err_guard(self.state, 0, || {
+ check_stack(self.state, 4);
+ push_string(self.state, registry_key)?;
+ protect_lua_call(self.state, 1, 1, |state| {
+ ffi::lua_gettable(state, ffi::LUA_REGISTRYINDEX)
+ })?;
+ T::from_lua(self.pop_value(self.state), self)
+ })
+ }
+ }
+
+ // Uses 1 stack space, does not call checkstack
pub(crate) unsafe fn push_value(&self, state: *mut ffi::lua_State, value: Value) {
match value {
Value::Nil => {
@@ -454,7 +488,7 @@ impl Lua {
}
}
- // Used 1 stack space, does not call checkstack
+ // Uses 1 stack space, does not call checkstack
pub(crate) unsafe fn pop_value(&self, state: *mut ffi::lua_State) -> Value {
match ffi::lua_type(state, -1) {
ffi::LUA_TNIL => {
@@ -510,9 +544,9 @@ impl Lua {
// Used 1 stack space, does not call checkstack
pub(crate) unsafe fn push_ref(&self, state: *mut ffi::lua_State, lref: &LuaRef) {
- assert_eq!(
- lref.lua.main_state,
- self.main_state,
+ lua_assert!(
+ state,
+ lref.lua.main_state == self.main_state,
"Lua instance passed Value created from a different Lua"
);
diff --git a/src/tests.rs b/src/tests.rs
index 418c3d1..1bbb6e1 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -499,6 +499,19 @@ fn test_gc_error() {
}
}
+#[test]
+fn test_registry() {
+ let lua = Lua::new();
+
+ lua.set_registry::<i32>("test", 42).unwrap();
+ let f = lua.create_function(move |lua, ()| {
+ assert_eq!(lua.get_registry::<i32>("test")?, 42);
+ Ok(())
+ }).unwrap();
+
+ f.call::<_, ()>(()).unwrap();
+}
+
// TODO: Need to use compiletest-rs or similar to make sure these don't compile.
/*
#[test]
diff --git a/src/util.rs b/src/util.rs
index db594da..aa203fc 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -211,12 +211,14 @@ pub unsafe fn pop_error(state: *mut ffi::lua_State, err_code: c_int) -> Error {
}
}
+// Internally uses 4 stack spaces, does not call checkstack
pub unsafe fn push_string(state: *mut ffi::lua_State, s: &str) -> Result<()> {
protect_lua_call(state, 0, 1, |state| {
ffi::lua_pushlstring(state, s.as_ptr() as *const c_char, s.len());
})
}
+// Internally uses 4 stack spaces, does not call checkstack
pub unsafe fn push_userdata<T>(state: *mut ffi::lua_State, t: T) -> Result<()> {
let mut t = Some(t);
protect_lua_call(state, 0, 1, |state| {