diff --git a/src/function.rs b/src/function.rs index f87d52c..cbb1415 100644 --- a/src/function.rs +++ b/src/function.rs @@ -6,7 +6,7 @@ use crate::error::{Error, Result}; use crate::ffi; use crate::types::LuaRef; 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")] use {futures_core::future::LocalBoxFuture, futures_util::future}; @@ -59,7 +59,7 @@ impl<'lua> Function<'lua> { pub fn call, R: FromLuaMulti<'lua>>(&self, args: A) -> Result { 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 results = unsafe { @@ -69,7 +69,7 @@ impl<'lua> Function<'lua> { ffi::lua_pushcfunction(lua.state, error_traceback); let stack_start = ffi::lua_gettop(lua.state); lua.push_ref(&self.0); - for arg in args { + for arg in args.drain_all() { lua.push_value(arg)?; } 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)); } 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); for _ in 0..nresults { results.push_front(lua.pop_value()); diff --git a/src/thread.rs b/src/thread.rs index aad1df2..b6d5f47 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -108,7 +108,7 @@ impl<'lua> Thread<'lua> { R: FromLuaMulti<'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 results = unsafe { let _sg = StackGuard::new(lua.state); @@ -123,7 +123,7 @@ impl<'lua> Thread<'lua> { } check_stack(thread_state, nargs)?; - for arg in args { + for arg in args.drain_all() { lua.push_value(arg)?; } ffi::lua_xmove(lua.state, thread_state, nargs); @@ -136,7 +136,7 @@ impl<'lua> Thread<'lua> { 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 ffi::lua_xmove(thread_state, lua.state, nresults); diff --git a/src/value.rs b/src/value.rs index e05fb0a..a93abc9 100644 --- a/src/value.rs +++ b/src/value.rs @@ -241,6 +241,11 @@ impl<'lua> MultiValue<'lua> { pub fn iter(&self) -> iter::Rev>> { self.0.iter().rev() } + + #[inline] + pub(crate) fn drain_all(&mut self) -> iter::Rev>> { + self.0.drain(..).rev() + } } /// Trait for types convertible to any number of Lua values.