From 9f02a9ca09f90082a9e0f8f2c52a331967db76a5 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Tue, 17 Aug 2021 15:17:03 +0100 Subject: [PATCH] Add `Debug::event()` to the hook's Debug structure --- src/hook.rs | 29 +++++++++++++++++++++++++++++ src/lib.rs | 2 +- tests/hooks.rs | 7 +++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/hook.rs b/src/hook.rs index 3004e42..e65c088 100644 --- a/src/hook.rs +++ b/src/hook.rs @@ -23,6 +23,25 @@ pub struct Debug<'a> { } impl<'a> Debug<'a> { + /// Returns the specific event that triggered the hook. + /// + /// For [Lua 5.1] `DebugEvent::TailCall` is used for return events to indicate a return + /// from a function that did a tail call. + /// + /// [Lua 5.1]: https://www.lua.org/manual/5.1/manual.html#pdf-LUA_HOOKTAILRET + pub fn event(&self) -> DebugEvent { + unsafe { + match (&*self.ar).event { + ffi::LUA_HOOKCALL => DebugEvent::Call, + ffi::LUA_HOOKRET => DebugEvent::Ret, + ffi::LUA_HOOKTAILCALL => DebugEvent::TailCall, + ffi::LUA_HOOKLINE => DebugEvent::Line, + ffi::LUA_HOOKCOUNT => DebugEvent::Count, + event => mlua_panic!("Unknown Lua event code: {}", event), + } + } + } + /// Corresponds to the `n` what mask. pub fn names(&self) -> DebugNames<'a> { unsafe { @@ -95,6 +114,16 @@ impl<'a> Debug<'a> { } } +/// Represents a specific event that triggered the hook. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum DebugEvent { + Call, + Ret, + TailCall, + Line, + Count, +} + #[derive(Clone, Debug)] pub struct DebugNames<'a> { pub name: Option<&'a [u8]>, diff --git a/src/lib.rs b/src/lib.rs index e4cb790..afbb456 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,7 +102,7 @@ pub use crate::{ffi::lua_CFunction, 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::hook::{Debug, DebugEvent, DebugNames, DebugSource, DebugStack, HookTriggers}; pub use crate::lua::{AsChunk, Chunk, ChunkMode, GCMode, Lua, LuaOptions}; pub use crate::multi::Variadic; pub use crate::scope::Scope; diff --git a/tests/hooks.rs b/tests/hooks.rs index 378c134..73a8888 100644 --- a/tests/hooks.rs +++ b/tests/hooks.rs @@ -3,7 +3,7 @@ use std::ops::Deref; use std::str; use std::sync::{Arc, Mutex}; -use mlua::{Error, HookTriggers, Lua, Result, Value}; +use mlua::{DebugEvent, Error, HookTriggers, Lua, Result, Value}; #[test] fn test_line_counts() -> Result<()> { @@ -17,6 +17,7 @@ fn test_line_counts() -> Result<()> { ..Default::default() }, move |_lua, debug| { + assert_eq!(debug.event(), DebugEvent::Line); hook_output.lock().unwrap().push(debug.curr_line()); Ok(()) }, @@ -54,6 +55,7 @@ fn test_function_calls() -> Result<()> { ..Default::default() }, move |_lua, debug| { + assert_eq!(debug.event(), DebugEvent::Call); let names = debug.names(); let source = debug.source(); let name = names.name.map(|s| str::from_utf8(s).unwrap().to_owned()); @@ -139,7 +141,8 @@ fn test_limit_execution_instructions() -> Result<()> { every_nth_instruction: Some(30), ..Default::default() }, - move |_lua, _debug| { + move |_lua, debug| { + assert_eq!(debug.event(), DebugEvent::Count); max_instructions -= 30; if max_instructions < 0 { Err(Error::RuntimeError("time's up".to_string()))