Enable hooks support for LuaJIT
This commit is contained in:
parent
0a13a9631d
commit
efcaef3db7
13
src/hook.rs
13
src/hook.rs
|
@ -1,8 +1,3 @@
|
|||
#![cfg_attr(
|
||||
not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51")),
|
||||
allow(dead_code)
|
||||
)]
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
@ -18,8 +13,6 @@ use crate::util::callback_error;
|
|||
/// Lua code executing at the time that the hook function was called. Further information can be
|
||||
/// found in the [Lua 5.3 documentaton][lua_doc].
|
||||
///
|
||||
/// Requires `feature = "lua54/lua53/lua52/lua51"`
|
||||
///
|
||||
/// [lua_doc]: https://www.lua.org/manual/5.3/manual.html#lua_Debug
|
||||
/// [`Lua::set_hook`]: struct.Lua.html#method.set_hook
|
||||
#[derive(Clone)]
|
||||
|
@ -93,9 +86,9 @@ impl<'a> Debug<'a> {
|
|||
);
|
||||
DebugStack {
|
||||
num_ups: (*self.ar).nups as i32,
|
||||
#[cfg(any(feature = "lua52", feature = "lua53", feature = "lua54"))]
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
num_params: (*self.ar).nparams as i32,
|
||||
#[cfg(any(feature = "lua52", feature = "lua53", feature = "lua54"))]
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
is_vararg: (*self.ar).isvararg != 0,
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +122,6 @@ pub struct DebugStack {
|
|||
}
|
||||
|
||||
/// Determines when a hook function will be called by Lua.
|
||||
///
|
||||
/// Requires `feature = "lua54/lua53/lua52/lua51"`
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct HookTriggers {
|
||||
/// Before a function call.
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -80,6 +80,7 @@ pub use crate::ffi::lua_State;
|
|||
|
||||
pub use crate::error::{Error, ExternalError, ExternalResult, Result};
|
||||
pub use crate::function::Function;
|
||||
pub use crate::hook::{Debug, DebugNames, DebugSource, DebugStack, HookTriggers};
|
||||
pub use crate::lua::{Chunk, GCMode, Lua};
|
||||
pub use crate::multi::Variadic;
|
||||
pub use crate::scope::Scope;
|
||||
|
@ -91,15 +92,6 @@ pub use crate::types::{Integer, LightUserData, Number, RegistryKey};
|
|||
pub use crate::userdata::{AnyUserData, MetaMethod, UserData, UserDataMethods};
|
||||
pub use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value};
|
||||
|
||||
#[cfg(any(
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "lua51",
|
||||
doc
|
||||
))]
|
||||
pub use crate::hook::{Debug, DebugNames, DebugSource, DebugStack, HookTriggers};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub use crate::thread::AsyncThread;
|
||||
|
||||
|
|
33
src/lua.rs
33
src/lua.rs
|
@ -10,6 +10,7 @@ use std::{mem, ptr, str};
|
|||
use crate::error::{Error, Result};
|
||||
use crate::ffi;
|
||||
use crate::function::Function;
|
||||
use crate::hook::{hook_proc, Debug, HookTriggers};
|
||||
use crate::scope::Scope;
|
||||
use crate::stdlib::StdLib;
|
||||
use crate::string::String;
|
||||
|
@ -27,15 +28,6 @@ use crate::util::{
|
|||
};
|
||||
use crate::value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value};
|
||||
|
||||
#[cfg(any(
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "lua51",
|
||||
doc
|
||||
))]
|
||||
use crate::hook::{hook_proc, Debug, HookTriggers};
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
use {
|
||||
crate::types::AsyncCallback,
|
||||
|
@ -430,16 +422,12 @@ impl Lua {
|
|||
/// limited form of execution limits by setting [`HookTriggers.every_nth_instruction`] and
|
||||
/// erroring once an instruction limit has been reached.
|
||||
///
|
||||
/// Requires `feature = "lua54/lua53/lua52/lua51"`
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Shows each line number of code being executed by the Lua interpreter.
|
||||
///
|
||||
/// ```
|
||||
/// # #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51"))]
|
||||
/// # use mlua::{Lua, HookTriggers, Result};
|
||||
/// # #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51"))]
|
||||
/// # fn main() -> Result<()> {
|
||||
/// let lua = Lua::new();
|
||||
/// lua.set_hook(HookTriggers {
|
||||
|
@ -455,20 +443,10 @@ impl Lua {
|
|||
/// local z = string.len(x..", "..y)
|
||||
/// "#).exec()
|
||||
/// # }
|
||||
///
|
||||
/// # #[cfg(not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51")))]
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
///
|
||||
/// [`HookTriggers`]: struct.HookTriggers.html
|
||||
/// [`HookTriggers.every_nth_instruction`]: struct.HookTriggers.html#field.every_nth_instruction
|
||||
#[cfg(any(
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "lua51",
|
||||
doc
|
||||
))]
|
||||
pub fn set_hook<F>(&self, triggers: HookTriggers, callback: F) -> Result<()>
|
||||
where
|
||||
F: 'static + MaybeSend + FnMut(&Lua, Debug) -> Result<()>,
|
||||
|
@ -484,15 +462,6 @@ impl Lua {
|
|||
|
||||
/// Remove any hook previously set by `set_hook`. This function has no effect if a hook was not
|
||||
/// previously set.
|
||||
///
|
||||
/// Requires `feature = "lua54/lua53/lua52/lua51"`
|
||||
#[cfg(any(
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "lua51",
|
||||
doc
|
||||
))]
|
||||
pub fn remove_hook(&self) {
|
||||
// If main_state is not available, then sethook wasn't called.
|
||||
let state = match self.main_state {
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
#![cfg(any(
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "lua51"
|
||||
))]
|
||||
#![cfg_attr(
|
||||
all(feature = "luajit", target_os = "macos", target_arch = "x86_64"),
|
||||
feature(link_args)
|
||||
)]
|
||||
|
||||
#[cfg_attr(
|
||||
all(feature = "luajit", target_os = "macos", target_arch = "x86_64"),
|
||||
link_args = "-pagezero_size 10000 -image_base 100000000",
|
||||
allow(unused_attributes)
|
||||
)]
|
||||
extern "system" {}
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Deref;
|
||||
|
@ -37,8 +42,14 @@ fn line_counts() -> Result<()> {
|
|||
)
|
||||
.exec()?;
|
||||
|
||||
lua.remove_hook();
|
||||
|
||||
let output = output.lock().unwrap();
|
||||
if cfg!(feature = "luajit") && lua.load("jit.version_num").eval::<i64>()? >= 20100 {
|
||||
assert_eq!(*output, vec![2, 3, 4, 0, 4]);
|
||||
} else {
|
||||
assert_eq!(*output, vec![2, 3, 4]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -71,7 +82,18 @@ fn function_calls() -> Result<()> {
|
|||
)
|
||||
.exec()?;
|
||||
|
||||
lua.remove_hook();
|
||||
|
||||
let output = output.lock().unwrap();
|
||||
if cfg!(feature = "luajit") && lua.load("jit.version_num").eval::<i64>()? >= 20100 {
|
||||
assert_eq!(
|
||||
*output,
|
||||
vec![
|
||||
(None, Some("main".to_string())),
|
||||
(Some("len".to_string()), Some("Lua".to_string()))
|
||||
]
|
||||
);
|
||||
} else {
|
||||
assert_eq!(
|
||||
*output,
|
||||
vec![
|
||||
|
@ -79,6 +101,7 @@ fn function_calls() -> Result<()> {
|
|||
(Some("len".to_string()), Some("C".to_string()))
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -119,6 +142,10 @@ fn limit_execution_instructions() -> Result<()> {
|
|||
let lua = Lua::new();
|
||||
let mut max_instructions = 10000;
|
||||
|
||||
#[cfg(feature = "luajit")]
|
||||
// For LuaJIT disable JIT, as compiled code does not trigger hooks
|
||||
lua.load("jit.off()").exec()?;
|
||||
|
||||
lua.set_hook(
|
||||
HookTriggers {
|
||||
every_nth_instruction: Some(30),
|
||||
|
|
Loading…
Reference in New Issue