mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
impl Drop for MultiValue
This action would automatically return container to the pool on drop (instead of doing it manually)
This commit is contained in:
+5
-7
@@ -107,7 +107,7 @@ pub(crate) struct ExtraData {
|
||||
// Pool of `WrappedFailure` enums in the ref thread (as userdata)
|
||||
wrapped_failure_pool: Vec<c_int>,
|
||||
// Pool of `MultiValue` containers
|
||||
multivalue_pool: Vec<MultiValue<'static>>,
|
||||
multivalue_pool: Vec<Vec<Value<'static>>>,
|
||||
// Pool of `Thread`s (coroutines) for async execution
|
||||
#[cfg(feature = "async")]
|
||||
thread_pool: Vec<c_int>,
|
||||
@@ -2898,8 +2898,7 @@ impl Lua {
|
||||
let lua: &Lua = mem::transmute((*extra).inner.assume_init_ref());
|
||||
let _guard = StateGuard::new(&lua.0, state);
|
||||
|
||||
let mut args = MultiValue::new_or_pooled(lua);
|
||||
args.reserve(nargs as usize);
|
||||
let mut args = MultiValue::with_lua_and_capacity(lua, nargs as usize);
|
||||
for _ in 0..nargs {
|
||||
args.push_front(lua.pop_value());
|
||||
}
|
||||
@@ -2943,7 +2942,6 @@ impl Lua {
|
||||
for r in results.drain_all() {
|
||||
lua.push_value(r)?;
|
||||
}
|
||||
MultiValue::return_to_pool(results, lua);
|
||||
Ok(nresults as c_int + 1)
|
||||
}
|
||||
_ => {
|
||||
@@ -3184,13 +3182,13 @@ impl LuaInner {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn new_multivalue_from_pool(&self) -> MultiValue {
|
||||
pub(crate) fn pop_multivalue_from_pool(&self) -> Option<Vec<Value>> {
|
||||
let extra = unsafe { &mut *self.extra.get() };
|
||||
extra.multivalue_pool.pop().unwrap_or_default()
|
||||
extra.multivalue_pool.pop()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn return_multivalue_to_pool(&self, mut multivalue: MultiValue) {
|
||||
pub(crate) fn push_multivalue_to_pool(&self, mut multivalue: Vec<Value>) {
|
||||
let extra = unsafe { &mut *self.extra.get() };
|
||||
if extra.multivalue_pool.len() < MULTIVALUE_POOL_SIZE {
|
||||
multivalue.clear();
|
||||
|
||||
+9
-16
@@ -13,7 +13,7 @@ use crate::value::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, MultiValue, Nil
|
||||
impl<'lua, T: IntoLua<'lua>, E: IntoLua<'lua>> IntoLuaMulti<'lua> for StdResult<T, E> {
|
||||
#[inline]
|
||||
fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
|
||||
let mut result = MultiValue::new_or_pooled(lua);
|
||||
let mut result = MultiValue::with_lua_and_capacity(lua, 2);
|
||||
match self {
|
||||
Ok(v) => result.push_front(v.into_lua(lua)?),
|
||||
Err(e) => {
|
||||
@@ -28,7 +28,7 @@ impl<'lua, T: IntoLua<'lua>, E: IntoLua<'lua>> IntoLuaMulti<'lua> for StdResult<
|
||||
impl<'lua, T: IntoLua<'lua>> IntoLuaMulti<'lua> for T {
|
||||
#[inline]
|
||||
fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
|
||||
let mut v = MultiValue::new_or_pooled(lua);
|
||||
let mut v = MultiValue::with_lua_and_capacity(lua, 1);
|
||||
v.push_front(self.into_lua(lua)?);
|
||||
Ok(v)
|
||||
}
|
||||
@@ -43,9 +43,7 @@ impl<'lua, T: IntoLua<'lua>> IntoLuaMulti<'lua> for T {
|
||||
impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for T {
|
||||
#[inline]
|
||||
fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let res = T::from_lua(values.pop_front().unwrap_or(Nil), lua);
|
||||
MultiValue::return_to_pool(values, lua);
|
||||
res
|
||||
T::from_lua(values.pop_front().unwrap_or(Nil), lua)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -55,9 +53,7 @@ impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for T {
|
||||
to: Option<&str>,
|
||||
lua: &'lua Lua,
|
||||
) -> Result<Self> {
|
||||
let res = T::from_lua_arg(args.pop_front().unwrap_or(Nil), i, to, lua);
|
||||
MultiValue::return_to_pool(args, lua);
|
||||
res
|
||||
T::from_lua_arg(args.pop_front().unwrap_or(Nil), i, to, lua)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -170,7 +166,7 @@ impl<T> DerefMut for Variadic<T> {
|
||||
impl<'lua, T: IntoLua<'lua>> IntoLuaMulti<'lua> for Variadic<T> {
|
||||
#[inline]
|
||||
fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
|
||||
let mut values = MultiValue::new_or_pooled(lua);
|
||||
let mut values = MultiValue::with_lua_and_capacity(lua, self.0.len());
|
||||
values.refill(self.0.into_iter().map(|e| e.into_lua(lua)))?;
|
||||
Ok(values)
|
||||
}
|
||||
@@ -179,13 +175,11 @@ impl<'lua, T: IntoLua<'lua>> IntoLuaMulti<'lua> for Variadic<T> {
|
||||
impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for Variadic<T> {
|
||||
#[inline]
|
||||
fn from_lua_multi(mut values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let res = values
|
||||
values
|
||||
.drain_all()
|
||||
.map(|e| T::from_lua(e, lua))
|
||||
.collect::<Result<Vec<T>>>()
|
||||
.map(Variadic);
|
||||
MultiValue::return_to_pool(values, lua);
|
||||
res
|
||||
.map(Variadic)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +188,7 @@ macro_rules! impl_tuple {
|
||||
impl<'lua> IntoLuaMulti<'lua> for () {
|
||||
#[inline]
|
||||
fn into_lua_multi(self, lua: &'lua Lua) -> Result<MultiValue<'lua>> {
|
||||
Ok(MultiValue::new_or_pooled(lua))
|
||||
Ok(MultiValue::with_lua_and_capacity(lua, 0))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -205,8 +199,7 @@ macro_rules! impl_tuple {
|
||||
|
||||
impl<'lua> FromLuaMulti<'lua> for () {
|
||||
#[inline]
|
||||
fn from_lua_multi(values: MultiValue<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
MultiValue::return_to_pool(values, lua);
|
||||
fn from_lua_multi(_values: MultiValue<'lua>, _lua: &'lua Lua) -> Result<Self> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
+57
-44
@@ -5,7 +5,7 @@ use std::ops::Index;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
use std::string::String as StdString;
|
||||
use std::sync::Arc;
|
||||
use std::{fmt, ptr, slice, str, vec};
|
||||
use std::{fmt, mem, ptr, slice, str, vec};
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
use {
|
||||
@@ -379,24 +379,43 @@ pub trait FromLua<'lua>: Sized {
|
||||
|
||||
/// Multiple Lua values used for both argument passing and also for multiple return values.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MultiValue<'lua>(Vec<Value<'lua>>);
|
||||
pub struct MultiValue<'lua> {
|
||||
vec: Vec<Value<'lua>>,
|
||||
lua: Option<&'lua Lua>,
|
||||
}
|
||||
|
||||
impl Drop for MultiValue<'_> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(lua) = self.lua {
|
||||
let vec = mem::replace(&mut self.vec, Vec::new());
|
||||
lua.push_multivalue_to_pool(vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> MultiValue<'lua> {
|
||||
/// Creates an empty `MultiValue` containing no values.
|
||||
pub const fn new() -> MultiValue<'lua> {
|
||||
MultiValue(Vec::new())
|
||||
MultiValue {
|
||||
vec: Vec::new(),
|
||||
lua: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Similar to `new` but can return previously used container with allocated capacity.
|
||||
/// Similar to `new` but can reuse previously used container with allocated capacity.
|
||||
#[inline]
|
||||
pub(crate) fn new_or_pooled(lua: &'lua Lua) -> MultiValue<'lua> {
|
||||
lua.new_multivalue_from_pool()
|
||||
}
|
||||
|
||||
/// Clears and returns previously allocated multivalue container to the pool.
|
||||
#[inline]
|
||||
pub(crate) fn return_to_pool(multivalue: Self, lua: &Lua) {
|
||||
lua.return_multivalue_to_pool(multivalue);
|
||||
pub(crate) fn with_lua_and_capacity(lua: &'lua Lua, capacity: usize) -> MultiValue<'lua> {
|
||||
let vec = lua
|
||||
.pop_multivalue_from_pool()
|
||||
.map(|mut vec| {
|
||||
vec.reserve(capacity);
|
||||
vec
|
||||
})
|
||||
.unwrap_or_else(|| Vec::with_capacity(capacity));
|
||||
MultiValue {
|
||||
vec,
|
||||
lua: Some(lua),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,8 +438,10 @@ impl<'lua> IntoIterator for MultiValue<'lua> {
|
||||
type IntoIter = iter::Rev<vec::IntoIter<Value<'lua>>>;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter().rev()
|
||||
fn into_iter(mut self) -> Self::IntoIter {
|
||||
let vec = mem::replace(&mut self.vec, Vec::new());
|
||||
mem::forget(self);
|
||||
vec.into_iter().rev()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,7 +451,7 @@ impl<'a, 'lua> IntoIterator for &'a MultiValue<'lua> {
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.iter().rev()
|
||||
self.vec.iter().rev()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,64 +474,60 @@ impl<'lua> Index<usize> for MultiValue<'lua> {
|
||||
|
||||
impl<'lua> MultiValue<'lua> {
|
||||
#[inline]
|
||||
pub fn from_vec(mut v: Vec<Value<'lua>>) -> MultiValue<'lua> {
|
||||
v.reverse();
|
||||
MultiValue(v)
|
||||
pub fn from_vec(mut vec: Vec<Value<'lua>>) -> MultiValue<'lua> {
|
||||
vec.reverse();
|
||||
MultiValue { vec, lua: None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_vec(self) -> Vec<Value<'lua>> {
|
||||
let mut v = self.0;
|
||||
v.reverse();
|
||||
v
|
||||
pub fn into_vec(mut self) -> Vec<Value<'lua>> {
|
||||
let mut vec = mem::replace(&mut self.vec, Vec::new());
|
||||
mem::forget(self);
|
||||
vec.reverse();
|
||||
vec
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<&Value<'lua>> {
|
||||
if index < self.0.len() {
|
||||
return self.0.get(self.0.len() - index - 1);
|
||||
if index < self.vec.len() {
|
||||
return self.vec.get(self.vec.len() - index - 1);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn reserve(&mut self, size: usize) {
|
||||
self.0.reserve(size);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pop_front(&mut self) -> Option<Value<'lua>> {
|
||||
self.0.pop()
|
||||
self.vec.pop()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push_front(&mut self, value: Value<'lua>) {
|
||||
self.0.push(value);
|
||||
self.vec.push(value);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear(&mut self) {
|
||||
self.0.clear();
|
||||
self.vec.clear();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
self.vec.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
self.vec.is_empty()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn iter(&self) -> iter::Rev<slice::Iter<Value<'lua>>> {
|
||||
self.0.iter().rev()
|
||||
self.vec.iter().rev()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn drain_all(&mut self) -> iter::Rev<vec::Drain<Value<'lua>>> {
|
||||
self.0.drain(..).rev()
|
||||
self.vec.drain(..).rev()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -518,11 +535,11 @@ impl<'lua> MultiValue<'lua> {
|
||||
&mut self,
|
||||
iter: impl IntoIterator<Item = Result<Value<'lua>>>,
|
||||
) -> Result<()> {
|
||||
self.0.clear();
|
||||
self.vec.clear();
|
||||
for value in iter {
|
||||
self.0.push(value?);
|
||||
self.vec.push(value?);
|
||||
}
|
||||
self.0.reverse();
|
||||
self.vec.reverse();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -543,15 +560,12 @@ pub trait IntoLuaMulti<'lua>: Sized {
|
||||
unsafe fn push_into_stack_multi(self, lua: &'lua Lua) -> Result<c_int> {
|
||||
let mut values = self.into_lua_multi(lua)?;
|
||||
let len: c_int = values.len().try_into().unwrap();
|
||||
|
||||
unsafe {
|
||||
check_stack(lua.state(), len + 1)?;
|
||||
for v in values.drain_all() {
|
||||
lua.push_value(v)?;
|
||||
}
|
||||
}
|
||||
MultiValue::return_to_pool(values, lua);
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
@@ -589,8 +603,7 @@ pub trait FromLuaMulti<'lua>: Sized {
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
unsafe fn from_stack_multi(nvals: c_int, lua: &'lua Lua) -> Result<Self> {
|
||||
let mut values = MultiValue::new_or_pooled(lua);
|
||||
values.reserve(nvals as usize);
|
||||
let mut values = MultiValue::with_lua_and_capacity(lua, nvals as usize);
|
||||
for idx in 1..=nvals {
|
||||
values.push_front(lua.stack_value(-idx));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user