API changes, inline more often
This commit is contained in:
parent
925a2816cc
commit
11d81209d9
|
@ -397,6 +397,7 @@ pub unsafe fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer {
|
|||
res
|
||||
}
|
||||
|
||||
// TODO: why not just checkstack and concat all at the end?
|
||||
pub unsafe fn luaL_traceback(
|
||||
L: *mut lua_State,
|
||||
L1: *mut lua_State,
|
||||
|
|
|
@ -38,30 +38,45 @@ impl<'lua> FromLua<'lua> for Value<'lua> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<String<'lua>> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: String<'lua>) -> Self {
|
||||
Value::String(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for String<'lua> {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::String(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> FromLua<'lua> for String<'lua> {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<String<'lua>> {
|
||||
let ty = value.type_name();
|
||||
lua.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "String",
|
||||
message: Some("expected string or number".to_string()),
|
||||
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<String<'lua>> {
|
||||
match value {
|
||||
Value::String(s) => Ok(s),
|
||||
_ => Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: "string",
|
||||
message: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<Table<'lua>> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: Table<'lua>) -> Self {
|
||||
Value::Table(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for Table<'lua> {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Table(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,10 +112,17 @@ impl<'lua> FromLua<'lua> for OwnedTable {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<Function<'lua>> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: Function<'lua>) -> Self {
|
||||
Value::Function(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for Function<'lua> {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Function(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,10 +173,17 @@ impl<'lua> IntoLua<'lua> for WrappedAsyncFunction<'lua> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<Thread<'lua>> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: Thread<'lua>) -> Self {
|
||||
Value::Thread(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for Thread<'lua> {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Thread(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,10 +201,17 @@ impl<'lua> FromLua<'lua> for Thread<'lua> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<AnyUserData<'lua>> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: AnyUserData<'lua>) -> Self {
|
||||
Value::UserData(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for AnyUserData<'lua> {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::UserData(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,49 +268,67 @@ impl<'lua, T: 'static> FromLua<'lua> for UserDataRefMut<'lua, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<Error> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: Error) -> Self {
|
||||
Value::Error(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for Error {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Error(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> FromLua<'lua> for Error {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Error> {
|
||||
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Error> {
|
||||
match value {
|
||||
Value::Error(err) => Ok(err),
|
||||
val => Ok(Error::RuntimeError(
|
||||
lua.coerce_string(val)?
|
||||
.and_then(|s| Some(s.to_str().ok()?.to_owned()))
|
||||
.unwrap_or_else(|| "<unprintable error>".to_owned()),
|
||||
)),
|
||||
_ => Err(Error::FromLuaConversionError { from: value.type_name(), to: "error", message: None }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<bool> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: bool) -> Self {
|
||||
Value::Boolean(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> IntoLua<'lua> for bool {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::Boolean(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> FromLua<'lua> for bool {
|
||||
#[inline]
|
||||
fn from_lua(v: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
||||
match v {
|
||||
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
||||
match value {
|
||||
Value::Nil => Ok(false),
|
||||
Value::Boolean(b) => Ok(b),
|
||||
_ => Ok(true),
|
||||
_ => Err(Error::FromLuaConversionError { from: value.type_name(), to: "boolean", message: None }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> From<LightUserData> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: LightUserData) -> Self {
|
||||
Value::LightUserData(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'lua> IntoLua<'lua> for LightUserData {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
Ok(Value::LightUserData(self))
|
||||
Ok(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,6 +346,15 @@ impl<'lua> FromLua<'lua> for LightUserData {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
impl<'lua> From<crate::types::Vector> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: crate::types::Vector) -> Self {
|
||||
Value::Vector(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "luau")]
|
||||
impl<'lua> IntoLua<'lua> for crate::types::Vector {
|
||||
#[inline]
|
||||
|
@ -325,16 +388,8 @@ impl<'lua> IntoLua<'lua> for StdString {
|
|||
impl<'lua> FromLua<'lua> for StdString {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
Ok(lua
|
||||
.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "String",
|
||||
message: Some("expected string or number".to_string()),
|
||||
})?
|
||||
.to_str()?
|
||||
.to_owned())
|
||||
let s = String::from_lua(value, lua)?;
|
||||
Ok(s.to_str()?.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,17 +417,7 @@ impl<'lua> IntoLua<'lua> for Box<str> {
|
|||
impl<'lua> FromLua<'lua> for Box<str> {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
Ok(lua
|
||||
.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "Box<str>",
|
||||
message: Some("expected string or number".to_string()),
|
||||
})?
|
||||
.to_str()?
|
||||
.to_owned()
|
||||
.into_boxed_str())
|
||||
StdString::from_lua(value, lua).map(|s| s.into_boxed_str())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,23 +431,15 @@ impl<'lua> IntoLua<'lua> for CString {
|
|||
impl<'lua> FromLua<'lua> for CString {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
let string = lua
|
||||
.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
let s = String::from_lua(value, lua)?;
|
||||
match CStr::from_bytes_with_nul(s.as_bytes_with_nul()) {
|
||||
Ok(s) => Ok(s.to_owned()),
|
||||
Err(e) => Err(Error::FromLuaConversionError {
|
||||
from: "string",
|
||||
to: "CString",
|
||||
message: Some("expected string or number".to_string()),
|
||||
})?;
|
||||
|
||||
match CStr::from_bytes_with_nul(string.as_bytes_with_nul()) {
|
||||
Ok(s) => Ok(s.into()),
|
||||
Err(_) => Err(Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "CString",
|
||||
message: Some("invalid C-style string".to_string()),
|
||||
message: Some(e.to_string()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -430,17 +467,8 @@ impl<'lua> IntoLua<'lua> for BString {
|
|||
impl<'lua> FromLua<'lua> for BString {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
Ok(BString::from(
|
||||
lua.coerce_string(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: "String",
|
||||
message: Some("expected string or number".to_string()),
|
||||
})?
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
))
|
||||
let s = String::from_lua(value, lua)?;
|
||||
Ok(BString::from(s.as_bytes().to_vec()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,9 +479,20 @@ impl<'lua> IntoLua<'lua> for &BStr {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! lua_convert_int_infallible {
|
||||
($($x:ty),*) => {
|
||||
$(impl<'lua> From<$x> for Value<'lua> {
|
||||
#[inline]
|
||||
fn from(value: $x) -> Self {
|
||||
Self::Integer(value.into())
|
||||
}
|
||||
})*
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! lua_convert_int {
|
||||
($x:ty) => {
|
||||
impl<'lua> IntoLua<'lua> for $x {
|
||||
($($x:ty),*) => {
|
||||
$(impl<'lua> IntoLua<'lua> for $x {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
cast(self)
|
||||
|
@ -470,53 +509,32 @@ macro_rules! lua_convert_int {
|
|||
|
||||
impl<'lua> FromLua<'lua> for $x {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
||||
(match value {
|
||||
Value::Integer(i) => cast(i),
|
||||
Value::Number(n) => cast(n),
|
||||
_ => {
|
||||
if let Some(i) = lua.coerce_integer(value.clone())? {
|
||||
cast(i)
|
||||
} else {
|
||||
cast(lua.coerce_number(value)?.ok_or_else(|| {
|
||||
Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: stringify!($x),
|
||||
message: Some(
|
||||
"expected number or string coercible to number".to_string(),
|
||||
),
|
||||
}
|
||||
})?)
|
||||
}
|
||||
}
|
||||
_ => return Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: stringify!($x),
|
||||
message: None,
|
||||
}),
|
||||
})
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
from: value.type_name(),
|
||||
to: stringify!($x),
|
||||
message: Some("out of range".to_owned()),
|
||||
})
|
||||
}
|
||||
}
|
||||
})*
|
||||
};
|
||||
}
|
||||
|
||||
lua_convert_int!(i8);
|
||||
lua_convert_int!(u8);
|
||||
lua_convert_int!(i16);
|
||||
lua_convert_int!(u16);
|
||||
lua_convert_int!(i32);
|
||||
lua_convert_int!(u32);
|
||||
lua_convert_int!(i64);
|
||||
lua_convert_int!(u64);
|
||||
lua_convert_int!(i128);
|
||||
lua_convert_int!(u128);
|
||||
lua_convert_int!(isize);
|
||||
lua_convert_int!(usize);
|
||||
lua_convert_int!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
|
||||
lua_convert_int_infallible!(i8, u8, i16, u16, i32);
|
||||
|
||||
macro_rules! lua_convert_float {
|
||||
($x:ty) => {
|
||||
impl<'lua> IntoLua<'lua> for $x {
|
||||
($($x:ty),*) => {
|
||||
$(impl<'lua> IntoLua<'lua> for $x {
|
||||
#[inline]
|
||||
fn into_lua(self, _: &'lua Lua) -> Result<Value<'lua>> {
|
||||
cast(self)
|
||||
|
@ -531,28 +549,27 @@ macro_rules! lua_convert_float {
|
|||
|
||||
impl<'lua> FromLua<'lua> for $x {
|
||||
#[inline]
|
||||
fn from_lua(value: Value<'lua>, lua: &'lua Lua) -> Result<Self> {
|
||||
let ty = value.type_name();
|
||||
lua.coerce_number(value)?
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
fn from_lua(value: Value<'lua>, _: &'lua Lua) -> Result<Self> {
|
||||
(match value {
|
||||
Value::Integer(i) => cast(i),
|
||||
Value::Number(n) => cast(n),
|
||||
_ => return Err(Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: stringify!($x),
|
||||
message: Some("expected number or string coercible to number".to_string()),
|
||||
})
|
||||
.and_then(|n| {
|
||||
cast(n).ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: ty,
|
||||
to: stringify!($x),
|
||||
message: Some("number out of range".to_string()),
|
||||
})
|
||||
})
|
||||
message: None,
|
||||
}),
|
||||
})
|
||||
.ok_or_else(|| Error::FromLuaConversionError {
|
||||
from: value.type_name(),
|
||||
to: stringify!($x),
|
||||
message: Some("out of range".to_owned()),
|
||||
})
|
||||
}
|
||||
}
|
||||
})*
|
||||
};
|
||||
}
|
||||
|
||||
lua_convert_float!(f32);
|
||||
lua_convert_float!(f64);
|
||||
lua_convert_float!(f32, f64);
|
||||
|
||||
impl<'lua, T> IntoLua<'lua> for &[T]
|
||||
where
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
pub use ::ffi::*;
|
||||
|
||||
use crate::util::{push_gc_userdata, WrappedFailure};
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn mlua_pusherror(state: *mut lua_State, err: crate::Error) -> crate::Result<()> {
|
||||
push_gc_userdata(state, WrappedFailure::Error(err), false)
|
||||
}
|
|
@ -83,6 +83,10 @@ pub struct CoverageInfo {
|
|||
}
|
||||
|
||||
impl<'lua> Function<'lua> {
|
||||
pub fn as_raw_ref(&self) -> &LuaRef<'lua> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Calls the function, passing `args` as function arguments.
|
||||
///
|
||||
/// The function's return values are converted to the generic type `R`.
|
||||
|
|
|
@ -82,6 +82,7 @@ mod macros;
|
|||
mod chunk;
|
||||
mod conversion;
|
||||
mod error;
|
||||
pub mod ffi;
|
||||
mod function;
|
||||
mod hook;
|
||||
mod lua;
|
||||
|
@ -103,7 +104,7 @@ mod value;
|
|||
|
||||
pub mod prelude;
|
||||
|
||||
pub use ffi::{lua_CFunction, lua_State};
|
||||
pub use self::ffi::{lua_CFunction, lua_State};
|
||||
|
||||
pub use crate::chunk::{AsChunk, Chunk, ChunkMode};
|
||||
pub use crate::error::{Error, ErrorContext, ExternalError, ExternalResult, Result};
|
||||
|
|
|
@ -1558,6 +1558,7 @@ impl Lua {
|
|||
///
|
||||
/// # Safety
|
||||
/// This function is unsafe because provides a way to execute unsafe C function.
|
||||
#[inline]
|
||||
pub unsafe fn create_c_function(&self, func: ffi::lua_CFunction) -> Result<Function> {
|
||||
let state = self.state();
|
||||
check_stack(state, 1)?;
|
||||
|
@ -2281,7 +2282,7 @@ impl Lua {
|
|||
extra.app_data.remove()
|
||||
}
|
||||
|
||||
// Uses 2 stack spaces, does not call checkstack
|
||||
/// Uses 2 stack spaces, does not call checkstack
|
||||
pub(crate) unsafe fn push_value(&self, value: Value) -> Result<()> {
|
||||
let state = self.state();
|
||||
match value {
|
||||
|
@ -2342,7 +2343,7 @@ impl Lua {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
// Uses 2 stack spaces, does not call checkstack
|
||||
/// Uses 2 stack spaces, does not call checkstack
|
||||
pub(crate) unsafe fn pop_value(&self) -> Value {
|
||||
let state = self.state();
|
||||
match ffi::lua_type(state, -1) {
|
||||
|
@ -2798,8 +2799,7 @@ impl Lua {
|
|||
))]
|
||||
unsafe {
|
||||
if !(*self.extra.get()).libs.contains(StdLib::COROUTINE) {
|
||||
load_from_std_lib(self.main_state, StdLib::COROUTINE)?;
|
||||
(*self.extra.get()).libs |= StdLib::COROUTINE;
|
||||
return Err(Error::RuntimeError("StdLib::COROUTINE is not loaded".to_owned()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,14 +69,23 @@ macro_rules! mlua_debug_assert {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
macro_rules! mlua_expect {
|
||||
($res:expr, $msg:expr) => {
|
||||
($res:expr, $msg:expr $(,)?) => {
|
||||
$res.expect(bug_msg!($msg))
|
||||
};
|
||||
}
|
||||
|
||||
($res:expr, $msg:expr,) => {
|
||||
mlua_expect!($res, $msg)
|
||||
};
|
||||
#[cfg(not(debug_assertions))]
|
||||
macro_rules! mlua_expect {
|
||||
($res:expr, $msg:expr $(,)?) => {{
|
||||
let x;
|
||||
#[allow(unused_unsafe)]
|
||||
{
|
||||
x = unsafe { $res.into_iter().next().unwrap_unchecked() };
|
||||
}
|
||||
x
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "module")]
|
||||
|
|
|
@ -41,6 +41,10 @@ impl OwnedString {
|
|||
}
|
||||
|
||||
impl<'lua> String<'lua> {
|
||||
pub fn as_raw_ref(&self) -> &LuaRef<'lua> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Get a `&str` slice if the Lua string is valid UTF-8.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -139,8 +143,7 @@ impl<'lua> String<'lua> {
|
|||
/// Typically this function is used only for hashing and debug information.
|
||||
#[inline]
|
||||
pub fn to_pointer(&self) -> *const c_void {
|
||||
let ref_thread = self.0.lua.ref_thread();
|
||||
unsafe { ffi::lua_topointer(ref_thread, self.0.index) }
|
||||
self.0.to_pointer()
|
||||
}
|
||||
|
||||
/// Convert this handle to owned version.
|
||||
|
|
19
src/table.rs
19
src/table.rs
|
@ -46,6 +46,10 @@ impl OwnedTable {
|
|||
}
|
||||
|
||||
impl<'lua> Table<'lua> {
|
||||
pub fn as_raw_ref(&self) -> &LuaRef<'lua> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Sets a key-value pair in the table.
|
||||
///
|
||||
/// If the value is `nil`, this will effectively remove the pair.
|
||||
|
@ -588,6 +592,7 @@ impl<'lua> Table<'lua> {
|
|||
/// Requires `feature = "luau"`
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
|
||||
#[inline]
|
||||
pub fn set_readonly(&self, enabled: bool) {
|
||||
let ref_thread = self.0.lua.ref_thread();
|
||||
unsafe {
|
||||
|
@ -599,11 +604,22 @@ impl<'lua> Table<'lua> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_safe(&self, enabled: bool) {
|
||||
let ref_thread = self.0.lua.ref_thread();
|
||||
let enabled = enabled as _;
|
||||
unsafe {
|
||||
ffi::lua_setreadonly(ref_thread, self.0.index, enabled);
|
||||
ffi::lua_setsafeenv(ref_thread, self.0.index, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `readonly` attribute of the table.
|
||||
///
|
||||
/// Requires `feature = "luau"`
|
||||
#[cfg(any(feature = "luau", doc))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
|
||||
#[inline]
|
||||
pub fn is_readonly(&self) -> bool {
|
||||
let ref_thread = self.0.lua.ref_thread();
|
||||
unsafe { ffi::lua_getreadonly(ref_thread, self.0.index) != 0 }
|
||||
|
@ -617,8 +633,7 @@ impl<'lua> Table<'lua> {
|
|||
/// Typically this function is used only for hashing and debug information.
|
||||
#[inline]
|
||||
pub fn to_pointer(&self) -> *const c_void {
|
||||
let ref_thread = self.0.lua.ref_thread();
|
||||
unsafe { ffi::lua_topointer(ref_thread, self.0.index) }
|
||||
self.0.to_pointer()
|
||||
}
|
||||
|
||||
/// Convert this handle to owned version.
|
||||
|
|
|
@ -73,6 +73,10 @@ pub struct AsyncThread<'lua, R> {
|
|||
}
|
||||
|
||||
impl<'lua> Thread<'lua> {
|
||||
pub fn as_raw_ref(&self) -> &LuaRef<'lua> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Resumes execution of this thread.
|
||||
///
|
||||
/// Equivalent to `coroutine.resume`.
|
||||
|
@ -88,6 +92,8 @@ impl<'lua> Thread<'lua> {
|
|||
/// If the thread calls `coroutine.yield`, returns the values passed to `yield`. If the thread
|
||||
/// `return`s values from its main function, returns those.
|
||||
///
|
||||
/// Also returns `true` if the coroutine is yielded.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -114,7 +120,7 @@ impl<'lua> Thread<'lua> {
|
|||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn resume<A, R>(&self, args: A) -> Result<R>
|
||||
pub fn resume<A, R>(&self, args: A) -> Result<(bool, R)>
|
||||
where
|
||||
A: IntoLuaMulti<'lua>,
|
||||
R: FromLuaMulti<'lua>,
|
||||
|
@ -124,7 +130,7 @@ impl<'lua> Thread<'lua> {
|
|||
|
||||
let mut args = args.into_lua_multi(lua)?;
|
||||
let nargs = args.len() as c_int;
|
||||
let results = unsafe {
|
||||
let (yielded, results) = unsafe {
|
||||
let _sg = StackGuard::new(state);
|
||||
check_stack(state, cmp::max(nargs + 1, 3))?;
|
||||
|
||||
|
@ -164,9 +170,9 @@ impl<'lua> Thread<'lua> {
|
|||
for _ in 0..nresults {
|
||||
results.push_front(lua.pop_value());
|
||||
}
|
||||
results
|
||||
(ret == ffi::LUA_YIELD, results)
|
||||
};
|
||||
R::from_lua_multi(results, lua)
|
||||
R::from_lua_multi(results, lua).map(|result| (yielded, result))
|
||||
}
|
||||
|
||||
/// Gets the status of the thread.
|
||||
|
@ -428,9 +434,9 @@ where
|
|||
// This is safe as we are not moving the whole struct
|
||||
let this = unsafe { self.get_unchecked_mut() };
|
||||
let ret: MultiValue = if let Some(args) = this.args0.take() {
|
||||
this.thread.resume(args?)?
|
||||
this.thread.resume(args?)?.1
|
||||
} else {
|
||||
this.thread.resume(())?
|
||||
this.thread.resume(())?.1
|
||||
};
|
||||
|
||||
if is_poll_pending(&ret) {
|
||||
|
@ -462,9 +468,9 @@ where
|
|||
// This is safe as we are not moving the whole struct
|
||||
let this = unsafe { self.get_unchecked_mut() };
|
||||
let ret: MultiValue = if let Some(args) = this.args0.take() {
|
||||
this.thread.resume(args?)?
|
||||
this.thread.resume(args?)?.1
|
||||
} else {
|
||||
this.thread.resume(())?
|
||||
this.thread.resume(())?.1
|
||||
};
|
||||
|
||||
if is_poll_pending(&ret) {
|
||||
|
|
|
@ -273,7 +273,7 @@ impl RegistryKey {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct LuaRef<'lua> {
|
||||
pub struct LuaRef<'lua> {
|
||||
pub(crate) lua: &'lua Lua,
|
||||
pub(crate) index: c_int,
|
||||
pub(crate) drop: bool,
|
||||
|
@ -296,6 +296,12 @@ impl<'lua> LuaRef<'lua> {
|
|||
mem::forget(self);
|
||||
owned_ref
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_pointer(&self) -> *const std::os::raw::c_void {
|
||||
let ref_thread = self.lua.ref_thread();
|
||||
unsafe { ffi::lua_topointer(ref_thread, self.index) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> fmt::Debug for LuaRef<'lua> {
|
||||
|
|
|
@ -806,6 +806,10 @@ impl OwnedAnyUserData {
|
|||
}
|
||||
|
||||
impl<'lua> AnyUserData<'lua> {
|
||||
pub fn as_raw_ref(&self) -> &LuaRef<'lua> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Checks whether the type of this userdata is `T`.
|
||||
pub fn is<T: 'static>(&self) -> bool {
|
||||
match self.inspect(|_: &UserDataCell<T>| Ok(())) {
|
||||
|
|
|
@ -360,6 +360,7 @@ pub unsafe fn take_userdata<T>(state: *mut ffi::lua_State) -> T {
|
|||
|
||||
// Pushes the userdata and attaches a metatable with __gc method.
|
||||
// Internally uses 3 stack spaces, does not call checkstack.
|
||||
#[inline]
|
||||
pub unsafe fn push_gc_userdata<T: Any>(
|
||||
state: *mut ffi::lua_State,
|
||||
t: T,
|
||||
|
@ -399,7 +400,7 @@ pub unsafe fn get_gc_userdata<T: Any>(
|
|||
}
|
||||
|
||||
unsafe extern "C" fn lua_error_impl(state: *mut ffi::lua_State) -> c_int {
|
||||
ffi::lua_error(state);
|
||||
ffi::lua_error(state)
|
||||
}
|
||||
|
||||
unsafe extern "C" fn lua_isfunction_impl(state: *mut ffi::lua_State) -> c_int {
|
||||
|
@ -629,6 +630,7 @@ pub unsafe extern "C" fn userdata_destructor<T>(state: *mut ffi::lua_State) -> c
|
|||
// This function uses some of the bottom of the stack for error handling, the given callback will be
|
||||
// given the number of arguments available as an argument, and should return the number of returns
|
||||
// as normal, but cannot assume that the arguments available start at 0.
|
||||
#[inline]
|
||||
pub unsafe fn callback_error<F, R>(state: *mut ffi::lua_State, f: F) -> R
|
||||
where
|
||||
F: FnOnce(c_int) -> Result<R>,
|
||||
|
@ -851,6 +853,7 @@ pub unsafe fn init_gc_metatable<T: Any>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn get_gc_metatable<T: Any>(state: *mut ffi::lua_State) {
|
||||
let type_id = TypeId::of::<T>();
|
||||
let ref_addr =
|
||||
|
|
20
src/value.rs
20
src/value.rs
|
@ -116,18 +116,14 @@ impl<'lua> Value<'lua> {
|
|||
/// Typically this function is used only for hashing and debug information.
|
||||
#[inline]
|
||||
pub fn to_pointer(&self) -> *const c_void {
|
||||
unsafe {
|
||||
match self {
|
||||
Value::LightUserData(ud) => ud.0,
|
||||
Value::Table(t) => t.to_pointer(),
|
||||
Value::String(s) => s.to_pointer(),
|
||||
Value::Function(Function(r))
|
||||
| Value::Thread(Thread(r))
|
||||
| Value::UserData(AnyUserData(r)) => {
|
||||
ffi::lua_topointer(r.lua.ref_thread(), r.index)
|
||||
}
|
||||
_ => ptr::null(),
|
||||
}
|
||||
match self {
|
||||
Value::LightUserData(ud) => ud.0,
|
||||
Value::Table(Table(r))
|
||||
| Value::String(String(r))
|
||||
| Value::Function(Function(r))
|
||||
| Value::Thread(Thread(r))
|
||||
| Value::UserData(AnyUserData(r)) => r.to_pointer(),
|
||||
_ => ptr::null(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue