Optimize MultiValue allocations (recycle old container)
This commit is contained in:
parent
6d689c35aa
commit
2c7d7117d2
|
@ -6,7 +6,7 @@ use crate::error::{Error, Result};
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
use crate::types::LuaRef;
|
use crate::types::LuaRef;
|
||||||
use crate::util::{assert_stack, check_stack, error_traceback, pop_error, StackGuard};
|
use crate::util::{assert_stack, check_stack, error_traceback, pop_error, StackGuard};
|
||||||
use crate::value::{FromLuaMulti, MultiValue, ToLuaMulti};
|
use crate::value::{FromLuaMulti, ToLuaMulti};
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
use {futures_core::future::LocalBoxFuture, futures_util::future};
|
use {futures_core::future::LocalBoxFuture, futures_util::future};
|
||||||
|
@ -59,7 +59,7 @@ impl<'lua> Function<'lua> {
|
||||||
pub fn call<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(&self, args: A) -> Result<R> {
|
pub fn call<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(&self, args: A) -> Result<R> {
|
||||||
let lua = self.0.lua;
|
let lua = self.0.lua;
|
||||||
|
|
||||||
let args = args.to_lua_multi(lua)?;
|
let mut args = args.to_lua_multi(lua)?;
|
||||||
let nargs = args.len() as c_int;
|
let nargs = args.len() as c_int;
|
||||||
|
|
||||||
let results = unsafe {
|
let results = unsafe {
|
||||||
|
@ -69,7 +69,7 @@ impl<'lua> Function<'lua> {
|
||||||
ffi::lua_pushcfunction(lua.state, error_traceback);
|
ffi::lua_pushcfunction(lua.state, error_traceback);
|
||||||
let stack_start = ffi::lua_gettop(lua.state);
|
let stack_start = ffi::lua_gettop(lua.state);
|
||||||
lua.push_ref(&self.0);
|
lua.push_ref(&self.0);
|
||||||
for arg in args {
|
for arg in args.drain_all() {
|
||||||
lua.push_value(arg)?;
|
lua.push_value(arg)?;
|
||||||
}
|
}
|
||||||
let ret = ffi::lua_pcall(lua.state, nargs, ffi::LUA_MULTRET, stack_start);
|
let ret = ffi::lua_pcall(lua.state, nargs, ffi::LUA_MULTRET, stack_start);
|
||||||
|
@ -77,7 +77,7 @@ impl<'lua> Function<'lua> {
|
||||||
return Err(pop_error(lua.state, ret));
|
return Err(pop_error(lua.state, ret));
|
||||||
}
|
}
|
||||||
let nresults = ffi::lua_gettop(lua.state) - stack_start;
|
let nresults = ffi::lua_gettop(lua.state) - stack_start;
|
||||||
let mut results = MultiValue::new();
|
let mut results = args; // Recycle MultiValue container
|
||||||
assert_stack(lua.state, 2);
|
assert_stack(lua.state, 2);
|
||||||
for _ in 0..nresults {
|
for _ in 0..nresults {
|
||||||
results.push_front(lua.pop_value());
|
results.push_front(lua.pop_value());
|
||||||
|
|
|
@ -108,7 +108,7 @@ impl<'lua> Thread<'lua> {
|
||||||
R: FromLuaMulti<'lua>,
|
R: FromLuaMulti<'lua>,
|
||||||
{
|
{
|
||||||
let lua = self.0.lua;
|
let lua = self.0.lua;
|
||||||
let args = args.to_lua_multi(lua)?;
|
let mut args = args.to_lua_multi(lua)?;
|
||||||
let nargs = args.len() as c_int;
|
let nargs = args.len() as c_int;
|
||||||
let results = unsafe {
|
let results = unsafe {
|
||||||
let _sg = StackGuard::new(lua.state);
|
let _sg = StackGuard::new(lua.state);
|
||||||
|
@ -123,7 +123,7 @@ impl<'lua> Thread<'lua> {
|
||||||
}
|
}
|
||||||
|
|
||||||
check_stack(thread_state, nargs)?;
|
check_stack(thread_state, nargs)?;
|
||||||
for arg in args {
|
for arg in args.drain_all() {
|
||||||
lua.push_value(arg)?;
|
lua.push_value(arg)?;
|
||||||
}
|
}
|
||||||
ffi::lua_xmove(lua.state, thread_state, nargs);
|
ffi::lua_xmove(lua.state, thread_state, nargs);
|
||||||
|
@ -136,7 +136,7 @@ impl<'lua> Thread<'lua> {
|
||||||
return Err(pop_error(thread_state, ret));
|
return Err(pop_error(thread_state, ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut results = MultiValue::new();
|
let mut results = args; // Recycle MultiValue container
|
||||||
check_stack(lua.state, nresults + 2)?; // 2 is extra for `lua.pop_value()` below
|
check_stack(lua.state, nresults + 2)?; // 2 is extra for `lua.pop_value()` below
|
||||||
ffi::lua_xmove(thread_state, lua.state, nresults);
|
ffi::lua_xmove(thread_state, lua.state, nresults);
|
||||||
|
|
||||||
|
|
|
@ -241,6 +241,11 @@ impl<'lua> MultiValue<'lua> {
|
||||||
pub fn iter(&self) -> iter::Rev<slice::Iter<Value<'lua>>> {
|
pub fn iter(&self) -> iter::Rev<slice::Iter<Value<'lua>>> {
|
||||||
self.0.iter().rev()
|
self.0.iter().rev()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn drain_all(&mut self) -> iter::Rev<vec::Drain<Value<'lua>>> {
|
||||||
|
self.0.drain(..).rev()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for types convertible to any number of Lua values.
|
/// Trait for types convertible to any number of Lua values.
|
||||||
|
|
Loading…
Reference in New Issue