Compare commits

...

4 Commits

Author SHA1 Message Date
Alex Orlenko c363fb9288 v0.5.3 2021-03-04 00:01:06 +00:00
Alex Orlenko 3900e23839 Fix compilation warnings on nightly 2021-03-03 23:36:28 +00:00
Alex Orlenko 726fde7e1f Optimise async callbacks (polling)
call async Rust callback [sum] 3 10
                        time:   [59.338 us 59.729 us 60.097 us]
                        change: [-10.336% -8.6212% -6.8003%] (p = 0.00 < 0.05)
                        Performance has improved.
2021-03-03 23:21:56 +00:00
Alex Orlenko 7cb9c4f39c Fix bug in returning nil-prefixed multi values from async function 2021-03-03 22:32:22 +00:00
9 changed files with 64 additions and 26 deletions
+5
View File
@@ -1,3 +1,8 @@
## v0.5.3
- Fixed bug when returning nil-prefixed multi values from async function (+ test)
- Performance optimisation for async callbacks (polling)
## v0.5.2
- Some performance optimisations (callbacks)
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "mlua"
version = "0.5.2" # remember to update html_root_url and mlua_derive
version = "0.5.3" # remember to update html_root_url and mlua_derive
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@chucklefish.org>"]
edition = "2018"
repository = "https://github.com/khvzak/mlua"
+5 -1
View File
@@ -13,6 +13,7 @@ extern "system" {}
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use std::time::Duration;
use tokio::runtime::Runtime;
use tokio::task;
use mlua::prelude::*;
@@ -117,7 +118,10 @@ fn call_sum_callback(c: &mut Criterion) {
fn call_async_sum_callback(c: &mut Criterion) {
let lua = Lua::new();
let callback = lua
.create_async_function(|_, (a, b, c): (i64, i64, i64)| async move { Ok(a + b + c) })
.create_async_function(|_, (a, b, c): (i64, i64, i64)| async move {
task::yield_now().await;
Ok(a + b + c)
})
.unwrap();
lua.globals().set("callback", callback).unwrap();
+1 -1
View File
@@ -70,7 +70,7 @@
//! [`serde::Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
// mlua types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/mlua/0.5.2")]
#![doc(html_root_url = "https://docs.rs/mlua/0.5.3")]
// Deny warnings inside doc tests / examples. When this isn't present, rustdoc doesn't show *any*
// warnings at all.
#![doc(test(attr(deny(warnings))))]
+21 -12
View File
@@ -1735,17 +1735,19 @@ impl Lua {
match (*fut).as_mut().poll(&mut ctx) {
Poll::Pending => {
check_stack(state, 6)?;
check_stack(state, 1)?;
ffi::lua_pushboolean(state, 0);
push_gc_userdata(state, AsyncPollPending)?;
Ok(2)
Ok(1)
}
Poll::Ready(results) => {
let results = lua.create_sequence_from(results?)?;
check_stack(state, 2)?;
let results = results?;
let nresults = results.len() as Integer;
let results = lua.create_sequence_from(results)?;
check_stack(state, 3)?;
ffi::lua_pushboolean(state, 1);
lua.push_value(Value::Table(results))?;
Ok(2)
lua.push_value(Value::Integer(nresults))?;
Ok(3)
}
}
})
@@ -1772,24 +1774,31 @@ impl Lua {
env.set("yield", coroutine.get::<_, Function>("yield")?)?;
env.set(
"unpack",
self.create_function(|_, tbl: Table| {
self.create_function(|_, (tbl, len): (Table, Integer)| {
Ok(MultiValue::from_vec(
tbl.sequence_values().collect::<Result<Vec<Value>>>()?,
tbl.raw_sequence_values_by_len(Some(len))
.collect::<Result<Vec<Value>>>()?,
))
})?,
)?;
env.set("pending", unsafe {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 5)?;
push_gc_userdata(self.state, AsyncPollPending)?;
self.pop_value()
})?;
// We set `poll` variable in the env table to be able to destroy upvalues
self.load(
r#"
poll = get_poll(...)
local poll, yield, unpack = poll, yield, unpack
local poll, pending, yield, unpack = poll, pending, yield, unpack
while true do
ready, res = poll()
local ready, res, nres = poll()
if ready then
return unpack(res)
return unpack(res, nres)
end
yield(res)
yield(pending)
end
"#,
)
+6 -4
View File
@@ -474,9 +474,11 @@ impl<'lua> Table<'lua> {
}
}
#[cfg(feature = "serialize")]
pub(crate) fn raw_sequence_values_by_len<V: FromLua<'lua>>(self) -> TableSequence<'lua, V> {
let len = self.raw_len();
pub(crate) fn raw_sequence_values_by_len<V: FromLua<'lua>>(
self,
len: Option<Integer>,
) -> TableSequence<'lua, V> {
let len = len.unwrap_or_else(|| self.raw_len());
TableSequence {
table: self.0,
index: Some(1),
@@ -641,7 +643,7 @@ impl<'lua> Serialize for Table<'lua> {
let len = self.raw_len() as usize;
if len > 0 || self.is_array() {
let mut seq = serializer.serialize_seq(Some(len))?;
for v in self.clone().raw_sequence_values_by_len::<Value>() {
for v in self.clone().raw_sequence_values_by_len::<Value>(None) {
let v = v.map_err(serde::ser::Error::custom)?;
seq.serialize_element(&v)?;
}
+18
View File
@@ -136,6 +136,24 @@ async fn test_async_handle_yield() -> Result<()> {
Ok(())
}
#[tokio::test]
async fn test_async_multi_return_nil() -> Result<()> {
let lua = Lua::new();
lua.globals().set(
"func",
lua.create_async_function(|_, _: ()| async { Ok((Option::<String>::None, "error")) })?,
)?;
lua.load(
r#"
local ok, err = func()
assert(err == "error")
"#,
)
.exec_async()
.await
}
#[tokio::test]
async fn test_async_return_async_closure() -> Result<()> {
let lua = Lua::new();
+5 -5
View File
@@ -19,7 +19,7 @@ fn test_serialize() -> Result<(), Box<dyn std::error::Error>> {
#[derive(Serialize)]
struct MyUserData(i64, String);
impl UserData for MyUserData {};
impl UserData for MyUserData {}
let lua = Lua::new();
let globals = lua.globals();
@@ -81,7 +81,7 @@ fn test_serialize_in_scope() -> LuaResult<()> {
#[derive(Serialize, Clone)]
struct MyUserData(i64, String);
impl UserData for MyUserData {};
impl UserData for MyUserData {}
let lua = Lua::new();
lua.scope(|scope| {
@@ -112,7 +112,7 @@ fn test_serialize_failure() -> Result<(), Box<dyn std::error::Error>> {
#[derive(Serialize)]
struct MyUserData(i64);
impl UserData for MyUserData {};
impl UserData for MyUserData {}
let lua = Lua::new();
@@ -148,7 +148,7 @@ fn test_to_value_struct() -> LuaResult<()> {
name: String,
key: i64,
data: Option<bool>,
};
}
let test = Test {
name: "alex".to_string(),
@@ -178,7 +178,7 @@ fn test_to_value_enum() -> LuaResult<()> {
name: String,
key: i64,
data: Option<bool>,
};
}
let test = Test {
name: "alex".to_string(),
+2 -2
View File
@@ -25,8 +25,8 @@ fn test_user_data() -> Result<()> {
struct UserData1(i64);
struct UserData2(Box<i64>);
impl UserData for UserData1 {};
impl UserData for UserData2 {};
impl UserData for UserData1 {}
impl UserData for UserData2 {}
let lua = Lua::new();
let userdata1 = lua.create_userdata(UserData1(1))?;