Working
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
__internal::{display, type_id},
|
||||
CDef, CDefBuilder, Metatype, MetatypeBuilder, ToFfi, Type, TypeBuilder,
|
||||
CDef, CDefBuilder, FfiReturnConvention, Metatype, MetatypeBuilder, ToFfi, Type, TypeBuilder,
|
||||
};
|
||||
use luaify::luaify;
|
||||
use std::{
|
||||
@@ -94,12 +94,9 @@ impl<F: Future<Output: ToFfi>> lua_future<F> {
|
||||
}
|
||||
|
||||
unsafe extern "C" fn take(&mut self) -> <F::Output as ToFfi>::To {
|
||||
// `fut:__take()` returns the fulfilled value by-value because it is the lowest common
|
||||
// denominator for supported return conventions (all `ToFfi` impls support return by-value;
|
||||
// primitives e.g. don't support return by out-param because they get boxed in cdata).
|
||||
//
|
||||
// Plus, if we preallocate a cdata for out-param and the thread for some reason gets dropped
|
||||
// and never resumed, GC could call the destructor on an uninitialised cdata.
|
||||
// `fut:__take()` returns the fulfilled value by-value (not by out-param) because if we
|
||||
// preallocate a cdata for the out-param and the thread for some reason gets dropped and
|
||||
// never resumed, the GC could call the destructor on an uninitialised cdata.
|
||||
match self.state {
|
||||
State::Fulfilled(_) => match mem::replace(&mut self.state, State::Complete) {
|
||||
State::Fulfilled(value) => value.convert(),
|
||||
@@ -170,7 +167,7 @@ unsafe impl<F: Future<Output: ToFfi> + 'static> ToFfi for lua_future<F> {
|
||||
self
|
||||
}
|
||||
|
||||
fn postlude(ret: &str) -> impl Display {
|
||||
fn postlude(ret: &str, _conv: FfiReturnConvention) -> impl Display {
|
||||
// When returning a future from Rust to Lua, yield it immediately to the runtime which will
|
||||
// poll it to completion in the background, then take the fulfilled value once the thread
|
||||
// gets resumed. Lua user code should never to worry about awaiting futures.
|
||||
@@ -181,7 +178,7 @@ unsafe impl<F: Future<Output: ToFfi> + 'static> ToFfi for lua_future<F> {
|
||||
// `coroutine.yield` is cached as `yield` and `ffi.gc` as `gc` in locals (see lib.rs)
|
||||
display!(
|
||||
"yield({ret}); {ret} = gc({ret}, nil):__take(); {}",
|
||||
<F::Output as ToFfi>::postlude(ret)
|
||||
<F::Output as ToFfi>::postlude(ret, FfiReturnConvention::ByValue)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user