Add Lua 5.4 (rc2) support
This commit is contained in:
parent
5c226b4915
commit
539b569ff4
|
@ -22,6 +22,19 @@ pub fn probe_lua() -> PathBuf {
|
||||||
|
|
||||||
// Find using via pkg-config
|
// Find using via pkg-config
|
||||||
|
|
||||||
|
#[cfg(feature = "lua54")]
|
||||||
|
{
|
||||||
|
let mut lua = pkg_config::Config::new()
|
||||||
|
.range_version((Bound::Included("5.4"), Bound::Excluded("5.5")))
|
||||||
|
.probe("lua");
|
||||||
|
|
||||||
|
if lua.is_err() {
|
||||||
|
lua = pkg_config::Config::new().probe("lua5.4");
|
||||||
|
}
|
||||||
|
|
||||||
|
return lua.unwrap().include_paths[0].clone();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(feature = "lua53")]
|
||||||
{
|
{
|
||||||
let mut lua = pkg_config::Config::new()
|
let mut lua = pkg_config::Config::new()
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52", feature = "lua51"))]
|
#[cfg(any(
|
||||||
|
feature = "lua54",
|
||||||
|
feature = "lua53",
|
||||||
|
feature = "lua52",
|
||||||
|
feature = "lua51"
|
||||||
|
))]
|
||||||
use lua_src;
|
use lua_src;
|
||||||
#[cfg(feature = "luajit")]
|
#[cfg(feature = "luajit")]
|
||||||
use luajit_src;
|
use luajit_src;
|
||||||
|
|
||||||
pub fn probe_lua() -> PathBuf {
|
pub fn probe_lua() -> PathBuf {
|
||||||
|
#[cfg(feature = "lua54")]
|
||||||
|
let artifacts = lua_src::Build::new().build(lua_src::Lua54);
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(feature = "lua53")]
|
||||||
let artifacts = lua_src::Build::new().build(lua_src::Lua53);
|
let artifacts = lua_src::Build::new().build(lua_src::Lua53);
|
||||||
#[cfg(feature = "lua52")]
|
#[cfg(feature = "lua52")]
|
||||||
|
|
|
@ -59,27 +59,36 @@ fn build_glue<P: AsRef<Path> + std::fmt::Debug>(include_path: &P) {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
|
feature = "lua54",
|
||||||
feature = "lua53",
|
feature = "lua53",
|
||||||
feature = "lua52",
|
feature = "lua52",
|
||||||
feature = "lua51",
|
feature = "lua51",
|
||||||
feature = "luajit"
|
feature = "luajit"
|
||||||
)))]
|
)))]
|
||||||
panic!("You must enable one of the features: lua53, lua52, lua51, luajit");
|
panic!("You must enable one of the features: lua54, lua53, lua52, lua51, luajit");
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "lua54",
|
||||||
|
any(
|
||||||
|
feature = "lua53",
|
||||||
|
feature = "lua52",
|
||||||
|
feature = "lua51",
|
||||||
|
feature = "luajit"
|
||||||
|
)
|
||||||
|
))]
|
||||||
|
panic!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit");
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "lua53",
|
feature = "lua53",
|
||||||
any(feature = "lua52", feature = "lua51", feature = "luajit")
|
any(feature = "lua52", feature = "lua51", feature = "luajit")
|
||||||
))]
|
))]
|
||||||
panic!("You can enable only one of the features: lua53, lua52, lua51, luajit");
|
panic!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit");
|
||||||
|
|
||||||
#[cfg(all(feature = "lua52", any(feature = "lua51", feature = "luajit")))]
|
#[cfg(all(feature = "lua52", any(feature = "lua51", feature = "luajit")))]
|
||||||
panic!("You can enable only one of the features: lua53, lua52, lua51, luajit");
|
panic!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit");
|
||||||
|
|
||||||
#[cfg(all(feature = "lua51", feature = "luajit"))]
|
#[cfg(all(feature = "lua51", feature = "luajit"))]
|
||||||
panic!("You can enable only one of the features: lua53, lua52, lua51, luajit");
|
panic!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit");
|
||||||
|
|
||||||
#[cfg(all(feature = "lua51", feature = "luajit"))]
|
|
||||||
panic!("You can enable only one of the features: lua53, lua52, lua51, luajit");
|
|
||||||
|
|
||||||
let include_dir = find::probe_lua();
|
let include_dir = find::probe_lua();
|
||||||
build_glue(&include_dir);
|
build_glue(&include_dir);
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub use crate::ffi::lua_State;
|
||||||
|
|
||||||
pub use crate::error::{Error, ExternalError, ExternalResult, Result};
|
pub use crate::error::{Error, ExternalError, ExternalResult, Result};
|
||||||
pub use crate::function::Function;
|
pub use crate::function::Function;
|
||||||
pub use crate::lua::{Chunk, Lua};
|
pub use crate::lua::{Chunk, GCMode, Lua};
|
||||||
pub use crate::multi::Variadic;
|
pub use crate::multi::Variadic;
|
||||||
pub use crate::scope::Scope;
|
pub use crate::scope::Scope;
|
||||||
pub use crate::stdlib::StdLib;
|
pub use crate::stdlib::StdLib;
|
||||||
|
|
97
src/lua.rs
97
src/lua.rs
|
@ -57,14 +57,28 @@ struct ExtraData {
|
||||||
ref_free: Vec<c_int>,
|
ref_free: Vec<c_int>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "send")]
|
/// Mode of the Lua garbage collector (GC).
|
||||||
unsafe impl Send for Lua {}
|
///
|
||||||
|
/// In Lua 5.4 GC can work in two modes: incremental and generational.
|
||||||
|
/// Previous Lua versions support only incremental GC.
|
||||||
|
///
|
||||||
|
/// More information can be found in the Lua 5.x [documentation][lua_doc].
|
||||||
|
///
|
||||||
|
/// [lua_doc]: https://www.lua.org/manual/5.4/manual.html#2.5
|
||||||
|
pub enum GCMode {
|
||||||
|
Incremental,
|
||||||
|
#[cfg(feature = "lua54")]
|
||||||
|
Generational,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
pub(crate) struct AsyncPollPending;
|
pub(crate) struct AsyncPollPending;
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
pub(crate) static WAKER_REGISTRY_KEY: u8 = 0;
|
pub(crate) static WAKER_REGISTRY_KEY: u8 = 0;
|
||||||
|
|
||||||
|
#[cfg(feature = "send")]
|
||||||
|
unsafe impl Send for Lua {}
|
||||||
|
|
||||||
impl Drop for Lua {
|
impl Drop for Lua {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -224,7 +238,7 @@ impl Lua {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the garbage collector is currently running automatically.
|
/// Returns true if the garbage collector is currently running automatically.
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
pub fn gc_is_running(&self) -> bool {
|
pub fn gc_is_running(&self) -> bool {
|
||||||
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCISRUNNING, 0) != 0 }
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCISRUNNING, 0) != 0 }
|
||||||
}
|
}
|
||||||
|
@ -287,13 +301,78 @@ impl Lua {
|
||||||
/// Sets the 'step multiplier' value of the collector.
|
/// Sets the 'step multiplier' value of the collector.
|
||||||
///
|
///
|
||||||
/// Returns the previous value of the 'step multiplier'. More information can be found in the
|
/// Returns the previous value of the 'step multiplier'. More information can be found in the
|
||||||
/// [Lua 5.3 documentation][lua_doc].
|
/// Lua 5.x [documentation][lua_doc].
|
||||||
///
|
///
|
||||||
/// [lua_doc]: https://www.lua.org/manual/5.3/manual.html#2.5
|
/// [lua_doc]: https://www.lua.org/manual/5.3/manual.html#2.5
|
||||||
pub fn gc_set_step_multiplier(&self, step_multiplier: c_int) -> c_int {
|
pub fn gc_set_step_multiplier(&self, step_multiplier: c_int) -> c_int {
|
||||||
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCSETSTEPMUL, step_multiplier) }
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCSETSTEPMUL, step_multiplier) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Changes the collector to incremental mode with the given parameters.
|
||||||
|
///
|
||||||
|
/// Returns the previous mode (always `GCMode::Incremental` in Lua < 5.4).
|
||||||
|
/// More information can be found in the Lua 5.x [documentation][lua_doc].
|
||||||
|
///
|
||||||
|
/// [lua_doc]: https://www.lua.org/manual/5.4/manual.html#2.5.1
|
||||||
|
pub fn gc_inc(&self, pause: c_int, step_multiplier: c_int, step_size: c_int) -> GCMode {
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "lua53",
|
||||||
|
feature = "lua52",
|
||||||
|
feature = "lua51",
|
||||||
|
feature = "luajit"
|
||||||
|
))]
|
||||||
|
{
|
||||||
|
if pause > 0 {
|
||||||
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCSETPAUSE, pause) };
|
||||||
|
}
|
||||||
|
if step_multiplier > 0 {
|
||||||
|
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCSETSTEPMUL, step_multiplier) };
|
||||||
|
}
|
||||||
|
let _ = step_size; // Ignored
|
||||||
|
return GCMode::Incremental;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "lua54")]
|
||||||
|
let prev_mode = unsafe {
|
||||||
|
ffi::lua_gc(
|
||||||
|
self.main_state,
|
||||||
|
ffi::LUA_GCSETPAUSE,
|
||||||
|
pause,
|
||||||
|
step_multiplier,
|
||||||
|
step_size,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
#[cfg(feature = "lua54")]
|
||||||
|
match prev_mode {
|
||||||
|
ffi::LUA_GCINC => GCMode::Incremental,
|
||||||
|
ffi::LUA_GCGEN => GCMode::Generational,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Changes the collector to generational mode with the given parameters.
|
||||||
|
///
|
||||||
|
/// Returns the previous mode. More information about the generational GC
|
||||||
|
/// can be found in the Lua 5.4 [documentation][lua_doc].
|
||||||
|
///
|
||||||
|
/// [lua_doc]: https://www.lua.org/manual/5.4/manual.html#2.5.2
|
||||||
|
#[cfg(feature = "lua54")]
|
||||||
|
pub fn gc_gen(&self, minor_multiplier: c_int, major_multiplier: c_int) -> GCMode {
|
||||||
|
let prev_mode = unsafe {
|
||||||
|
ffi::lua_gc(
|
||||||
|
self.main_state,
|
||||||
|
ffi::LUA_GCGEN,
|
||||||
|
minor_multiplier,
|
||||||
|
major_multiplier,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
match prev_mode {
|
||||||
|
ffi::LUA_GCGEN => GCMode::Generational,
|
||||||
|
ffi::LUA_GCINC => GCMode::Incremental,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns Lua source code as a `Chunk` builder type.
|
/// Returns Lua source code as a `Chunk` builder type.
|
||||||
///
|
///
|
||||||
/// In order to actually compile or run the resulting code, you must call [`Chunk::exec`] or
|
/// In order to actually compile or run the resulting code, you must call [`Chunk::exec`] or
|
||||||
|
@ -343,7 +422,7 @@ impl Lua {
|
||||||
ffi::LUA_OK => {
|
ffi::LUA_OK => {
|
||||||
if let Some(env) = env {
|
if let Some(env) = env {
|
||||||
self.push_value(env)?;
|
self.push_value(env)?;
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
ffi::lua_setupvalue(self.state, -2, 1);
|
ffi::lua_setupvalue(self.state, -2, 1);
|
||||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||||
ffi::lua_setfenv(self.state, -2);
|
ffi::lua_setfenv(self.state, -2);
|
||||||
|
@ -595,7 +674,7 @@ impl Lua {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _sg = StackGuard::new(self.state);
|
let _sg = StackGuard::new(self.state);
|
||||||
assert_stack(self.state, 2);
|
assert_stack(self.state, 2);
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
ffi::lua_rawgeti(self.state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
|
ffi::lua_rawgeti(self.state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
|
||||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||||
ffi::lua_pushvalue(self.state, ffi::LUA_GLOBALSINDEX);
|
ffi::lua_pushvalue(self.state, ffi::LUA_GLOBALSINDEX);
|
||||||
|
@ -1214,7 +1293,7 @@ impl Lua {
|
||||||
where
|
where
|
||||||
'lua: 'callback,
|
'lua: 'callback,
|
||||||
{
|
{
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
self.load_from_std_lib(StdLib::COROUTINE)?;
|
self.load_from_std_lib(StdLib::COROUTINE)?;
|
||||||
|
|
||||||
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
|
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
|
||||||
|
@ -1521,7 +1600,7 @@ impl<'lua, 'a> Chunk<'lua, 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn load_from_std_lib(state: *mut ffi::lua_State, libs: StdLib) {
|
unsafe fn load_from_std_lib(state: *mut ffi::lua_State, libs: StdLib) {
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
{
|
{
|
||||||
if libs.contains(StdLib::COROUTINE) {
|
if libs.contains(StdLib::COROUTINE) {
|
||||||
let colib_name = CString::new(ffi::LUA_COLIBNAME).unwrap();
|
let colib_name = CString::new(ffi::LUA_COLIBNAME).unwrap();
|
||||||
|
@ -1554,7 +1633,7 @@ unsafe fn load_from_std_lib(state: *mut ffi::lua_State, libs: StdLib) {
|
||||||
ffi::lua_pop(state, 1);
|
ffi::lua_pop(state, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
{
|
{
|
||||||
if libs.contains(StdLib::UTF8) {
|
if libs.contains(StdLib::UTF8) {
|
||||||
let utf8lib_name = CString::new(ffi::LUA_UTF8LIBNAME).unwrap();
|
let utf8lib_name = CString::new(ffi::LUA_UTF8LIBNAME).unwrap();
|
||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
AnyUserData as LuaAnyUserData, Chunk as LuaChunk, Error as LuaError,
|
AnyUserData as LuaAnyUserData, Chunk as LuaChunk, Error as LuaError,
|
||||||
ExternalError as LuaExternalError, ExternalResult as LuaExternalResult, FromLua, FromLuaMulti,
|
ExternalError as LuaExternalError, ExternalResult as LuaExternalResult, FromLua, FromLuaMulti,
|
||||||
Function as LuaFunction, Integer as LuaInteger, LightUserData as LuaLightUserData, Lua,
|
Function as LuaFunction, GCMode as LuaGCMode, Integer as LuaInteger,
|
||||||
MetaMethod as LuaMetaMethod, MultiValue as LuaMultiValue, Nil as LuaNil, Number as LuaNumber,
|
LightUserData as LuaLightUserData, Lua, MetaMethod as LuaMetaMethod,
|
||||||
RegistryKey as LuaRegistryKey, Result as LuaResult, String as LuaString, Table as LuaTable,
|
MultiValue as LuaMultiValue, Nil as LuaNil, Number as LuaNumber, RegistryKey as LuaRegistryKey,
|
||||||
TableExt as LuaTableExt, TablePairs as LuaTablePairs, TableSequence as LuaTableSequence,
|
Result as LuaResult, String as LuaString, Table as LuaTable, TableExt as LuaTableExt,
|
||||||
Thread as LuaThread, ThreadStatus as LuaThreadStatus, ToLua, ToLuaMulti,
|
TablePairs as LuaTablePairs, TableSequence as LuaTableSequence, Thread as LuaThread,
|
||||||
UserData as LuaUserData, UserDataMethods as LuaUserDataMethods, Value as LuaValue,
|
ThreadStatus as LuaThreadStatus, ToLua, ToLuaMulti, UserData as LuaUserData,
|
||||||
|
UserDataMethods as LuaUserDataMethods, Value as LuaValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "async")]
|
#[cfg(feature = "async")]
|
||||||
|
|
|
@ -282,7 +282,7 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||||
assert_stack(lua.state, 6);
|
assert_stack(lua.state, 6);
|
||||||
|
|
||||||
push_userdata(lua.state, ())?;
|
push_userdata(lua.state, ())?;
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
ffi::lua_pushlightuserdata(lua.state, data.as_ptr() as *mut c_void);
|
ffi::lua_pushlightuserdata(lua.state, data.as_ptr() as *mut c_void);
|
||||||
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
||||||
protect_lua_closure(lua.state, 0, 1, |state| {
|
protect_lua_closure(lua.state, 0, 1, |state| {
|
||||||
|
@ -383,7 +383,7 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
|
||||||
// We know the destructor has not run yet because we hold a reference to the callback.
|
// We know the destructor has not run yet because we hold a reference to the callback.
|
||||||
|
|
||||||
// First, get the environment table
|
// First, get the environment table
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
ffi::lua_getupvalue(state, -1, 1);
|
ffi::lua_getupvalue(state, -1, 1);
|
||||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||||
ffi::lua_getfenv(state, -1);
|
ffi::lua_getfenv(state, -1);
|
||||||
|
|
|
@ -6,13 +6,13 @@ use std::u32;
|
||||||
pub struct StdLib(u32);
|
pub struct StdLib(u32);
|
||||||
|
|
||||||
impl StdLib {
|
impl StdLib {
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
pub const COROUTINE: StdLib = StdLib(1 << 0);
|
pub const COROUTINE: StdLib = StdLib(1 << 0);
|
||||||
pub const TABLE: StdLib = StdLib(1 << 1);
|
pub const TABLE: StdLib = StdLib(1 << 1);
|
||||||
pub const IO: StdLib = StdLib(1 << 2);
|
pub const IO: StdLib = StdLib(1 << 2);
|
||||||
pub const OS: StdLib = StdLib(1 << 3);
|
pub const OS: StdLib = StdLib(1 << 3);
|
||||||
pub const STRING: StdLib = StdLib(1 << 4);
|
pub const STRING: StdLib = StdLib(1 << 4);
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
pub const UTF8: StdLib = StdLib(1 << 5);
|
pub const UTF8: StdLib = StdLib(1 << 5);
|
||||||
#[cfg(any(feature = "lua52", feature = "luajit"))]
|
#[cfg(any(feature = "lua52", feature = "luajit"))]
|
||||||
pub const BIT: StdLib = StdLib(1 << 6);
|
pub const BIT: StdLib = StdLib(1 << 6);
|
||||||
|
|
|
@ -129,7 +129,9 @@ impl<'lua> Thread<'lua> {
|
||||||
}
|
}
|
||||||
ffi::lua_xmove(lua.state, thread_state, nargs);
|
ffi::lua_xmove(lua.state, thread_state, nargs);
|
||||||
|
|
||||||
let ret = ffi::lua_resume(thread_state, lua.state, nargs);
|
let mut nresults = 0;
|
||||||
|
|
||||||
|
let ret = ffi::lua_resume(thread_state, lua.state, nargs, &mut nresults as *mut c_int);
|
||||||
if ret != ffi::LUA_OK && ret != ffi::LUA_YIELD {
|
if ret != ffi::LUA_OK && ret != ffi::LUA_YIELD {
|
||||||
protect_lua_closure(lua.state, 0, 0, |_| {
|
protect_lua_closure(lua.state, 0, 0, |_| {
|
||||||
error_traceback(thread_state);
|
error_traceback(thread_state);
|
||||||
|
@ -138,7 +140,6 @@ impl<'lua> Thread<'lua> {
|
||||||
return Err(pop_error(thread_state, ret));
|
return Err(pop_error(thread_state, ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
let nresults = ffi::lua_gettop(thread_state);
|
|
||||||
let mut results = MultiValue::new();
|
let mut results = MultiValue::new();
|
||||||
ffi::lua_xmove(thread_state, lua.state, nresults);
|
ffi::lua_xmove(thread_state, lua.state, nresults);
|
||||||
|
|
||||||
|
|
|
@ -34,25 +34,25 @@ pub enum MetaMethod {
|
||||||
Pow,
|
Pow,
|
||||||
/// The unary minus (`-`) operator.
|
/// The unary minus (`-`) operator.
|
||||||
Unm,
|
Unm,
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
/// The floor division (//) operator.
|
/// The floor division (//) operator.
|
||||||
IDiv,
|
IDiv,
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
/// The bitwise AND (&) operator.
|
/// The bitwise AND (&) operator.
|
||||||
BAnd,
|
BAnd,
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
/// The bitwise OR (|) operator.
|
/// The bitwise OR (|) operator.
|
||||||
BOr,
|
BOr,
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
/// The bitwise XOR (binary ~) operator.
|
/// The bitwise XOR (binary ~) operator.
|
||||||
BXor,
|
BXor,
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
/// The bitwise NOT (unary ~) operator.
|
/// The bitwise NOT (unary ~) operator.
|
||||||
BNot,
|
BNot,
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
/// The bitwise left shift (<<) operator.
|
/// The bitwise left shift (<<) operator.
|
||||||
Shl,
|
Shl,
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
/// The bitwise right shift (>>) operator.
|
/// The bitwise right shift (>>) operator.
|
||||||
Shr,
|
Shr,
|
||||||
/// The string concatenation operator `..`.
|
/// The string concatenation operator `..`.
|
||||||
|
@ -75,7 +75,7 @@ pub enum MetaMethod {
|
||||||
///
|
///
|
||||||
/// This is not an operator, but will be called by methods such as `tostring` and `print`.
|
/// This is not an operator, but will be called by methods such as `tostring` and `print`.
|
||||||
ToString,
|
ToString,
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
/// The `__pairs` metamethod.
|
/// The `__pairs` metamethod.
|
||||||
///
|
///
|
||||||
/// This is not an operator, but it will be called by the built-in `pairs` function.
|
/// This is not an operator, but it will be called by the built-in `pairs` function.
|
||||||
|
@ -92,19 +92,19 @@ impl MetaMethod {
|
||||||
MetaMethod::Mod => b"__mod",
|
MetaMethod::Mod => b"__mod",
|
||||||
MetaMethod::Pow => b"__pow",
|
MetaMethod::Pow => b"__pow",
|
||||||
MetaMethod::Unm => b"__unm",
|
MetaMethod::Unm => b"__unm",
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
MetaMethod::IDiv => b"__idiv",
|
MetaMethod::IDiv => b"__idiv",
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
MetaMethod::BAnd => b"__band",
|
MetaMethod::BAnd => b"__band",
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
MetaMethod::BOr => b"__bor",
|
MetaMethod::BOr => b"__bor",
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
MetaMethod::BXor => b"__bxor",
|
MetaMethod::BXor => b"__bxor",
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
MetaMethod::BNot => b"__bnot",
|
MetaMethod::BNot => b"__bnot",
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
MetaMethod::Shl => b"__shl",
|
MetaMethod::Shl => b"__shl",
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
MetaMethod::Shr => b"__shr",
|
MetaMethod::Shr => b"__shr",
|
||||||
MetaMethod::Concat => b"__concat",
|
MetaMethod::Concat => b"__concat",
|
||||||
MetaMethod::Len => b"__len",
|
MetaMethod::Len => b"__len",
|
||||||
|
@ -115,7 +115,7 @@ impl MetaMethod {
|
||||||
MetaMethod::NewIndex => b"__newindex",
|
MetaMethod::NewIndex => b"__newindex",
|
||||||
MetaMethod::Call => b"__call",
|
MetaMethod::Call => b"__call",
|
||||||
MetaMethod::ToString => b"__tostring",
|
MetaMethod::ToString => b"__tostring",
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
MetaMethod::Pairs => b"__pairs",
|
MetaMethod::Pairs => b"__pairs",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,18 +387,19 @@ impl<'lua> AnyUserData<'lua> {
|
||||||
/// Sets an associated value to this `AnyUserData`.
|
/// Sets an associated value to this `AnyUserData`.
|
||||||
///
|
///
|
||||||
/// The value may be any Lua value whatsoever, and can be retrieved with [`get_user_value`].
|
/// The value may be any Lua value whatsoever, and can be retrieved with [`get_user_value`].
|
||||||
|
/// As Lua < 5.3 allows to store only tables, the value will be stored in a table at index 1.
|
||||||
///
|
///
|
||||||
/// [`get_user_value`]: #method.get_user_value
|
/// [`get_user_value`]: #method.get_user_value
|
||||||
pub fn set_user_value<V: ToLua<'lua>>(&self, v: V) -> Result<()> {
|
pub fn set_user_value<V: ToLua<'lua>>(&self, v: V) -> Result<()> {
|
||||||
let lua = self.0.lua;
|
let lua = self.0.lua;
|
||||||
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
||||||
let v = {
|
let v = {
|
||||||
// Lua 5.2/5.1 allows to store only table. Then we will wrap the value.
|
// Lua 5.2/5.1 allows to store only a table. Then we will wrap the value.
|
||||||
let t = lua.create_table()?;
|
let t = lua.create_table()?;
|
||||||
t.raw_set(1, v)?;
|
t.raw_set(1, v)?;
|
||||||
crate::Value::Table(t)
|
crate::Value::Table(t)
|
||||||
};
|
};
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
let v = v.to_lua(lua)?;
|
let v = v.to_lua(lua)?;
|
||||||
unsafe {
|
unsafe {
|
||||||
let _sg = StackGuard::new(lua.state);
|
let _sg = StackGuard::new(lua.state);
|
||||||
|
@ -412,6 +413,8 @@ impl<'lua> AnyUserData<'lua> {
|
||||||
|
|
||||||
/// Returns an associated value set by [`set_user_value`].
|
/// Returns an associated value set by [`set_user_value`].
|
||||||
///
|
///
|
||||||
|
/// For Lua < 5.3 the value will be automatically extracted from the table wrapper from index 1.
|
||||||
|
///
|
||||||
/// [`set_user_value`]: #method.set_user_value
|
/// [`set_user_value`]: #method.set_user_value
|
||||||
pub fn get_user_value<V: FromLua<'lua>>(&self) -> Result<V> {
|
pub fn get_user_value<V: FromLua<'lua>>(&self) -> Result<V> {
|
||||||
let lua = self.0.lua;
|
let lua = self.0.lua;
|
||||||
|
@ -424,7 +427,7 @@ impl<'lua> AnyUserData<'lua> {
|
||||||
};
|
};
|
||||||
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
||||||
return crate::Table::from_lua(res, lua)?.get(1);
|
return crate::Table::from_lua(res, lua)?.get(1);
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
V::from_lua(res, lua)
|
V::from_lua(res, lua)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -485,7 +485,7 @@ pub unsafe extern "C" fn error_traceback(state: *mut ffi::lua_State) -> c_int {
|
||||||
|
|
||||||
// Does not call lua_checkstack, uses 1 stack space.
|
// Does not call lua_checkstack, uses 1 stack space.
|
||||||
pub unsafe fn get_main_state(state: *mut ffi::lua_State) -> *mut ffi::lua_State {
|
pub unsafe fn get_main_state(state: *mut ffi::lua_State) -> *mut ffi::lua_State {
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
{
|
{
|
||||||
ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_MAINTHREAD);
|
ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_MAINTHREAD);
|
||||||
let main_state = ffi::lua_tothread(state, -1);
|
let main_state = ffi::lua_tothread(state, -1);
|
||||||
|
|
|
@ -7,7 +7,7 @@ fn test_gc_control() -> Result<()> {
|
||||||
let lua = Lua::new();
|
let lua = Lua::new();
|
||||||
let globals = lua.globals();
|
let globals = lua.globals();
|
||||||
|
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
{
|
{
|
||||||
assert!(lua.gc_is_running());
|
assert!(lua.gc_is_running());
|
||||||
lua.gc_stop();
|
lua.gc_stop();
|
||||||
|
|
|
@ -389,7 +389,7 @@ fn test_num_conversion() -> Result<()> {
|
||||||
|
|
||||||
assert_eq!(lua.load("1.0").eval::<i64>()?, 1);
|
assert_eq!(lua.load("1.0").eval::<i64>()?, 1);
|
||||||
assert_eq!(lua.load("1.0").eval::<f64>()?, 1.0);
|
assert_eq!(lua.load("1.0").eval::<f64>()?, 1.0);
|
||||||
#[cfg(feature = "lua53")]
|
#[cfg(any(feature = "lua54", feature = "lua53"))]
|
||||||
assert_eq!(lua.load("1.0").eval::<String>()?, "1.0");
|
assert_eq!(lua.load("1.0").eval::<String>()?, "1.0");
|
||||||
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
|
||||||
assert_eq!(lua.load("1.0").eval::<String>()?, "1");
|
assert_eq!(lua.load("1.0").eval::<String>()?, "1");
|
||||||
|
@ -466,7 +466,12 @@ fn test_pcall_xpcall() -> Result<()> {
|
||||||
assert_eq!(globals.get::<_, String>("pcall_error")?, "testerror");
|
assert_eq!(globals.get::<_, String>("pcall_error")?, "testerror");
|
||||||
|
|
||||||
assert_eq!(globals.get::<_, bool>("xpcall_statusr")?, false);
|
assert_eq!(globals.get::<_, bool>("xpcall_statusr")?, false);
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52", feature = "luajit"))]
|
#[cfg(any(
|
||||||
|
feature = "lua54",
|
||||||
|
feature = "lua53",
|
||||||
|
feature = "lua52",
|
||||||
|
feature = "luajit"
|
||||||
|
))]
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
globals.get::<_, std::string::String>("xpcall_error")?,
|
globals.get::<_, std::string::String>("xpcall_error")?,
|
||||||
"testerror"
|
"testerror"
|
||||||
|
@ -799,7 +804,7 @@ fn context_thread() -> Result<()> {
|
||||||
)
|
)
|
||||||
.into_function()?;
|
.into_function()?;
|
||||||
|
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
f.call::<_, ()>(lua.current_thread())?;
|
f.call::<_, ()>(lua.current_thread())?;
|
||||||
|
|
||||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||||
|
|
|
@ -100,7 +100,12 @@ fn coroutine_from_closure() -> Result<()> {
|
||||||
let thrd_main = lua.create_function(|_, ()| Ok(()))?;
|
let thrd_main = lua.create_function(|_, ()| Ok(()))?;
|
||||||
lua.globals().set("main", thrd_main)?;
|
lua.globals().set("main", thrd_main)?;
|
||||||
|
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52", feature = "luajit"))]
|
#[cfg(any(
|
||||||
|
feature = "lua54",
|
||||||
|
feature = "lua53",
|
||||||
|
feature = "lua52",
|
||||||
|
feature = "luajit"
|
||||||
|
))]
|
||||||
let thrd: Thread = lua.load("coroutine.create(main)").eval()?;
|
let thrd: Thread = lua.load("coroutine.create(main)").eval()?;
|
||||||
#[cfg(feature = "lua51")]
|
#[cfg(feature = "lua51")]
|
||||||
let thrd: Thread = lua
|
let thrd: Thread = lua
|
||||||
|
|
|
@ -95,7 +95,7 @@ fn test_metamethods() -> Result<()> {
|
||||||
Err("no such custom index".to_lua_err())
|
Err("no such custom index".to_lua_err())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
methods.add_meta_method(MetaMethod::Pairs, |lua, data, ()| {
|
methods.add_meta_method(MetaMethod::Pairs, |lua, data, ()| {
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
let stateless_iter = lua.create_function(|_, (data, i): (MyUserData, i64)| {
|
let stateless_iter = lua.create_function(|_, (data, i): (MyUserData, i64)| {
|
||||||
|
@ -120,7 +120,7 @@ fn test_metamethods() -> Result<()> {
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
let pairs_it = {
|
let pairs_it = {
|
||||||
lua.load(
|
lua.load(
|
||||||
r#"
|
r#"
|
||||||
|
@ -140,7 +140,7 @@ fn test_metamethods() -> Result<()> {
|
||||||
assert_eq!(lua.load("userdata1 - userdata2").eval::<MyUserData>()?.0, 4);
|
assert_eq!(lua.load("userdata1 - userdata2").eval::<MyUserData>()?.0, 4);
|
||||||
assert_eq!(lua.load("userdata1:get()").eval::<i64>()?, 7);
|
assert_eq!(lua.load("userdata1:get()").eval::<i64>()?, 7);
|
||||||
assert_eq!(lua.load("userdata2.inner").eval::<i64>()?, 3);
|
assert_eq!(lua.load("userdata2.inner").eval::<i64>()?, 3);
|
||||||
#[cfg(any(feature = "lua53", feature = "lua52"))]
|
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||||
assert_eq!(pairs_it.call::<_, i64>(())?, 28);
|
assert_eq!(pairs_it.call::<_, i64>(())?, 28);
|
||||||
assert!(lua.load("userdata2.nonexist_field").eval::<()>().is_err());
|
assert!(lua.load("userdata2.nonexist_field").eval::<()>().is_err());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue