mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9c2b8d306 | |||
| d672e19365 | |||
| bda399a5b4 | |||
| fe5e87b0f5 |
+2
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mlua"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@chucklefish.org>"]
|
||||
edition = "2018"
|
||||
repository = "https://github.com/khvzak/mlua"
|
||||
@@ -38,6 +38,7 @@ async = ["futures-core", "futures-task", "futures-util"]
|
||||
|
||||
[dependencies]
|
||||
bstr = { version = "0.2", features = ["std"], default_features = false }
|
||||
lazy_static = { version = "1.4" }
|
||||
num-traits = { version = "0.2.11" }
|
||||
futures-core = { version = "0.3.4", optional = true }
|
||||
futures-task = { version = "0.3.4", optional = true }
|
||||
|
||||
@@ -373,6 +373,50 @@ macro_rules! lua_convert_float {
|
||||
lua_convert_float!(f32);
|
||||
lua_convert_float!(f64);
|
||||
|
||||
impl<'lua, T> ToLua<'lua> for &'_ [T]
|
||||
where
|
||||
T: Clone + ToLua<'lua>,
|
||||
{
|
||||
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Table(
|
||||
lua.create_sequence_from(self.into_iter().cloned())?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! lua_convert_array {
|
||||
($($N:literal)+) => {
|
||||
$(
|
||||
impl<'lua, T> ToLua<'lua> for [T; $N]
|
||||
where
|
||||
T: Clone + ToLua<'lua>,
|
||||
{
|
||||
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
||||
(&self).to_lua(lua)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua, T> ToLua<'lua> for &'_ [T; $N]
|
||||
where
|
||||
T: Clone + ToLua<'lua>,
|
||||
{
|
||||
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Table(
|
||||
lua.create_sequence_from(self.iter().cloned())?,
|
||||
))
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
lua_convert_array! {
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
10 11 12 13 14 15 16 17 18 19
|
||||
20 21 22 23 24 25 26 27 28 29
|
||||
30 31 32
|
||||
}
|
||||
|
||||
impl<'lua, T: ToLua<'lua>> ToLua<'lua> for Vec<T> {
|
||||
fn to_lua(self, lua: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Table(lua.create_sequence_from(self)?))
|
||||
|
||||
+4
-2
@@ -1234,9 +1234,11 @@ impl Lua {
|
||||
Function(self.pop_ref())
|
||||
};
|
||||
|
||||
let coroutine = self.globals().get::<_, Table>("coroutine")?;
|
||||
|
||||
let env = self.create_table()?;
|
||||
env.set("get_poll", get_poll)?;
|
||||
env.set("coroutine", self.globals().get::<_, Value>("coroutine")?)?;
|
||||
env.set("yield", coroutine.get::<_, Function>("yield")?)?;
|
||||
env.set(
|
||||
"unpack",
|
||||
self.create_function(|_, tbl: Table| {
|
||||
@@ -1254,7 +1256,7 @@ impl Lua {
|
||||
if ready then
|
||||
return unpack(res)
|
||||
end
|
||||
coroutine.yield(res)
|
||||
yield(res)
|
||||
end
|
||||
"#,
|
||||
)
|
||||
|
||||
+20
-8
@@ -1,18 +1,19 @@
|
||||
use std::any::{Any, TypeId};
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Write;
|
||||
use std::os::raw::{c_char, c_int, c_void};
|
||||
use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
use std::{mem, ptr, slice};
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
use crate::ffi;
|
||||
|
||||
thread_local! {
|
||||
static METATABLE_CACHE: RefCell<HashMap<TypeId, c_int>> = RefCell::new(HashMap::new());
|
||||
lazy_static::lazy_static! {
|
||||
// The capacity must(!) be greater than number of stored keys
|
||||
static ref METATABLE_CACHE: Mutex<HashMap<TypeId, u8>> = Mutex::new(HashMap::with_capacity(32));
|
||||
}
|
||||
|
||||
// Checks that Lua has enough free stack space for future stack operations. On failure, this will
|
||||
@@ -519,6 +520,16 @@ pub unsafe fn init_gc_metatable_for<T: Any>(
|
||||
) {
|
||||
let type_id = TypeId::of::<T>();
|
||||
|
||||
let ref_addr = {
|
||||
let mut mt_cache = mlua_expect!(METATABLE_CACHE.lock(), "cannot lock metatable cache");
|
||||
mlua_assert!(
|
||||
mt_cache.capacity() - mt_cache.len() > 0,
|
||||
"out of metatable cache capacity"
|
||||
);
|
||||
mt_cache.insert(type_id, 0);
|
||||
&mt_cache[&type_id] as *const u8
|
||||
};
|
||||
|
||||
ffi::lua_newtable(state);
|
||||
|
||||
ffi::lua_pushstring(state, cstr!("__gc"));
|
||||
@@ -533,15 +544,16 @@ pub unsafe fn init_gc_metatable_for<T: Any>(
|
||||
f(state)
|
||||
}
|
||||
|
||||
let ref_addr = ffi::luaL_ref(state, ffi::LUA_REGISTRYINDEX);
|
||||
METATABLE_CACHE.with(|mc| mc.borrow_mut().insert(type_id, ref_addr));
|
||||
ffi::lua_rawsetp(state, ffi::LUA_REGISTRYINDEX, ref_addr as *mut c_void);
|
||||
}
|
||||
|
||||
pub unsafe fn get_gc_metatable_for<T: Any>(state: *mut ffi::lua_State) {
|
||||
let type_id = TypeId::of::<T>();
|
||||
let ref_addr = METATABLE_CACHE
|
||||
.with(|mc| *mlua_expect!(mc.borrow().get(&type_id), "gc metatable does not exist"));
|
||||
ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ref_addr as ffi::lua_Integer);
|
||||
let ref_addr = {
|
||||
let mt_cache = mlua_expect!(METATABLE_CACHE.lock(), "cannot lock metatable cache");
|
||||
mlua_expect!(mt_cache.get(&type_id), "gc metatable does not exist") as *const u8
|
||||
};
|
||||
ffi::lua_rawgetp(state, ffi::LUA_REGISTRYINDEX, ref_addr as *mut c_void);
|
||||
}
|
||||
|
||||
// Initialize the error, panic, and destructed userdata metatables.
|
||||
|
||||
@@ -109,6 +109,47 @@ fn test_table() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_table_sequence_from() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
let get_table = lua.create_function(|_, t: Table| Ok(t))?;
|
||||
|
||||
assert_eq!(
|
||||
get_table
|
||||
.call::<_, Table>(vec![1, 2, 3])?
|
||||
.sequence_values()
|
||||
.collect::<Result<Vec<i64>>>()?,
|
||||
vec![1, 2, 3]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
get_table
|
||||
.call::<_, Table>([1, 2, 3].as_ref())?
|
||||
.sequence_values()
|
||||
.collect::<Result<Vec<i64>>>()?,
|
||||
vec![1, 2, 3]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
get_table
|
||||
.call::<_, Table>([1, 2, 3])?
|
||||
.sequence_values()
|
||||
.collect::<Result<Vec<i64>>>()?,
|
||||
vec![1, 2, 3]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
get_table
|
||||
.call::<_, Table>(&[1, 2, 3])?
|
||||
.sequence_values()
|
||||
.collect::<Result<Vec<i64>>>()?,
|
||||
vec![1, 2, 3]
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_table_scope() -> Result<()> {
|
||||
let lua = Lua::new();
|
||||
|
||||
Reference in New Issue
Block a user