Add signature check to lua_pollable

This commit is contained in:
2025-06-21 06:04:50 +10:00
parent 728ee58e0d
commit 5be3f2970c
2 changed files with 65 additions and 43 deletions

View File

@@ -11,6 +11,7 @@ use std::{
marker::PhantomData,
ops::{Deref, DerefMut},
os::raw::{c_char, c_int, c_void},
pin::Pin,
process,
ptr::{self, NonNull},
rc::Rc,
@@ -981,26 +982,26 @@ impl Stack {
loop {
match self.resume(narg)? {
ResumeStatus::Ok => {
let n = self.size() - base;
break Ok(if nret == LUA_MULTRET {
n
if nret == LUA_MULTRET {
break Ok(self.size() - base);
} else {
self.resize(nret);
nret
});
self.resize(base + nret);
break Ok(nret);
}
}
ResumeStatus::Suspended => {
narg = 0;
self.resize(1);
let value = self.slot(1);
let ptr = value.cdata::<lua_pollable>().cast_mut();
if ptr.is_null() {
return Err(Error::InvalidType(
"cdata<struct lua_pollable>",
value.type_of().name(),
));
} else {
unsafe { (&mut *ptr).await }
narg = 0;
let ptr = self.slot(1).cdata::<lua_pollable>().cast_mut();
if !ptr.is_null() {
// SAFETY: rust futures boxed in cdata payloads are never moved by the GC so
// we can safely make a Pin out of this pointer. see also comments in
// `luaffi::future::lua_future<T>`.
let fut = unsafe { Pin::new_unchecked(&mut *ptr) };
if fut.is_valid() {
fut.await;
}
}
}
}