Skip to content

Commit 6844445

Browse files
committed
More abstractions
- Add LuaApi.equal, LuaApi.rawequal - Update example code - Add DebugInfo struct which is higher level and rename previous struct to RawDebugInfo - Add LuaApi.getfenv and LuaApi.getinfo
1 parent b019b30 commit 6844445

File tree

7 files changed

+131
-23
lines changed

7 files changed

+131
-23
lines changed

packages/autorun-env/src/env.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,15 @@ impl EnvHandle {
6767
}
6868

6969
pub fn is_active(&self, lua: &LuaApi, state: *mut LuaState) -> bool {
70-
if lua.raw.getinfo(state, 1, c"f").is_none() {
71-
// No function info available
70+
let Ok(info) = lua.getinfo(state, 1, c"f") else {
7271
return false;
73-
}
74-
75-
lua.raw.getfenv(state, -1);
76-
lua.raw.push(state, self);
72+
};
7773

78-
let equal = lua.raw.rawequal(state, -1, -2);
79-
lua.raw.pop(state, 3);
74+
let Ok(Some(env)) = lua.getfenv(state, &info.func.unwrap()) else {
75+
return false;
76+
};
8077

81-
equal
78+
lua.equal(state, &env, &self.env)
8279
}
8380

8481
pub fn get_active_plugin(&self, lua: &LuaApi, state: *mut LuaState) -> Option<&Plugin> {

packages/autorun-env/src/functions/auth.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use anyhow::Context;
2-
use autorun_lua::{DebugInfo, LuaApi};
2+
use autorun_lua::{LuaApi, RawDebugInfo};
33
use autorun_luajit::{Frame, GCProto, LJ_TPROTO, LJState, get_gcobj, index2adr, push_tvalue};
44
use autorun_types::LuaState;
55

@@ -13,7 +13,7 @@ pub fn is_function_authorized(lua: &LuaApi, state: *mut LuaState, env: crate::En
1313

1414
if lua.raw.typeid(state, 1) == autorun_lua::LuaTypeId::Number {
1515
// attempt to resolve the function at the given stack level
16-
let mut debug_info = unsafe { std::mem::zeroed::<DebugInfo>() };
16+
let mut debug_info = unsafe { std::mem::zeroed::<RawDebugInfo>() };
1717
let stack_level = lua.raw.try_to::<i32>(state, 1)?;
1818
lua.raw.pop(state, 1); // remove the stack level argument
1919

@@ -49,8 +49,7 @@ pub fn is_proto_authorized(_lua: &LuaApi, state: *mut LuaState, env: crate::EnvH
4949

5050
let proto_gc = get_gcobj::<GCProto>(lj_state, 1).context("Failed to get GCProto for given index.")?;
5151
let proto_chunk_name = proto_gc.chunk_name_str().context("Failed to get chunk name from proto.")?;
52-
let proto_chunk_name_cstr =
53-
std::ffi::CString::new(proto_chunk_name.clone()).context("Failed to convert chunk name to CString.")?;
52+
let proto_chunk_name_cstr = std::ffi::CString::new(proto_chunk_name).context("Failed to convert chunk name to CString.")?;
5453

5554
Ok(env.is_chunk_name_authorized(&proto_chunk_name_cstr))
5655
}

packages/autorun-lua/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ This implements Autorun's lua abstractions and being able to access the lua api
1111
use autorun_lua::*;
1212

1313
fn lua_adder(lua: &LuaApi, state: *mut LuaState) -> Result<f64, Box<dyn std::error::Error>> {
14-
let x = lua.check_number(state, 1);
15-
let y = lua.check_number(state, 2);
14+
let x = lua.raw.try_to::<f64>(state, 1)?;
15+
let y = lua.raw.try_to::<f64>(state, 2)?;
1616

1717
// This pushes it onto lua's stack for you.
1818
// You can return multiple values via a tuple of values

packages/autorun-lua/examples/basic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
use autorun_lua::*;
55

66
fn lua_adder(lua: &LuaApi, state: *mut LuaState) -> Result<f64, Box<dyn std::error::Error>> {
7-
let x = lua.check_number(state, 1);
8-
let y = lua.check_number(state, 2);
7+
let x = lua.raw.try_to::<f64>(state, 1)?;
8+
let y = lua.raw.try_to::<f64>(state, 2)?;
99

1010
// This pushes it onto lua's stack for you.
1111
// You can return multiple values via a tuple of values

packages/autorun-lua/src/lua/mod.rs

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,29 @@ pub use result::*;
77
mod returns;
88
pub use returns::*;
99

10-
use crate::{FromLua, IntoLua, LuaFunction, LuaTable, LuaValue, types::LuaState};
11-
use std::ffi::{CStr, c_char, c_int};
10+
use crate::{IntoLua, LuaFunction, LuaTable, LuaValue, types::LuaState};
11+
use std::ffi::{CStr, c_int};
1212

1313
#[derive(Debug)]
1414
pub struct LuaApi {
1515
pub raw: RawLuaApi,
1616
}
1717

18+
#[derive(Debug)]
19+
pub struct DebugInfo {
20+
pub event: c_int,
21+
pub name: Option<String>, // n
22+
pub namewhat: Option<String>, // n
23+
pub what: Option<String>, // S
24+
pub source: Option<String>, // S
25+
pub currentline: Option<c_int>, // l
26+
pub nups: Option<c_int>, // u
27+
pub linedefined: Option<c_int>, // S
28+
pub lastlinedefined: Option<c_int>, // S
29+
pub short_src: Option<String>, // S
30+
pub func: Option<LuaFunction>, // f
31+
}
32+
1833
impl LuaApi {
1934
pub fn new(lib: &libloading::Library) -> Result<Self, libloading::Error> {
2035
let raw = RawLuaApi::new(lib)?;
@@ -39,6 +54,15 @@ impl LuaApi {
3954
Ok(())
4055
}
4156

57+
pub fn getfenv(&self, state: *mut LuaState, f: &LuaFunction) -> LuaResult<Option<LuaTable>> {
58+
self.raw.push(state, f);
59+
self.raw.getfenv(state, -1);
60+
let env: Option<LuaTable> = self.raw.try_to(state, -1)?;
61+
self.raw.pop(state, 2);
62+
63+
Ok(env)
64+
}
65+
4266
pub fn getregistry(&self, state: *mut LuaState, key: impl IntoLua) -> LuaValue<'_> {
4367
key.into_lua(&self.raw, state);
4468
self.raw.rawget(state, REGISTRY_INDEX);
@@ -57,6 +81,83 @@ impl LuaApi {
5781
self.raw.push(state, msg);
5882
self.raw.error(state);
5983
}
84+
85+
pub fn equal(&self, state: *mut LuaState, a: impl IntoLua, b: impl IntoLua) -> bool {
86+
a.into_lua(&self.raw, state);
87+
b.into_lua(&self.raw, state);
88+
let result = self.raw.equal(state, -2, -1);
89+
self.raw.pop(state, 2);
90+
result
91+
}
92+
93+
pub fn rawequal(&self, state: *mut LuaState, a: impl IntoLua, b: impl IntoLua) -> bool {
94+
a.into_lua(&self.raw, state);
95+
b.into_lua(&self.raw, state);
96+
let result = self.raw.rawequal(state, -2, -1);
97+
self.raw.pop(state, 2);
98+
result
99+
}
100+
101+
pub fn getinfo(&self, state: *mut LuaState, level: c_int, select: &CStr) -> LuaResult<DebugInfo> {
102+
let info = self.raw.getinfo(state, level, select).ok_or(LuaError::GenericFailure)?;
103+
let select = select.to_bytes();
104+
105+
let mut name = None;
106+
let mut namewhat = None;
107+
let mut what = None;
108+
let mut source = None;
109+
let mut currentline = None;
110+
let mut nups = None;
111+
let mut linedefined = None;
112+
let mut lastlinedefined = None;
113+
let mut short_src = None;
114+
let mut func = None;
115+
116+
if select.contains(&b'f') {
117+
let f: LuaFunction = self.raw.try_to(state, -1)?;
118+
self.raw.pop(state, 1);
119+
func = Some(f);
120+
}
121+
122+
if select.contains(&b'n') {
123+
name = Some(unsafe { CStr::from_ptr(info.name) }.to_string_lossy().to_string());
124+
namewhat = Some(unsafe { CStr::from_ptr(info.namewhat) }.to_string_lossy().to_string());
125+
}
126+
127+
if select.contains(&b'S') {
128+
what = Some(unsafe { CStr::from_ptr(info.what) }.to_string_lossy().to_string());
129+
source = Some(unsafe { CStr::from_ptr(info.source) }.to_string_lossy().to_string());
130+
linedefined = Some(info.linedefined);
131+
lastlinedefined = Some(info.lastlinedefined);
132+
short_src = Some(
133+
unsafe { CStr::from_ptr(info.short_src.as_ptr()) }
134+
.to_string_lossy()
135+
.to_string(),
136+
);
137+
}
138+
139+
if select.contains(&b'l') {
140+
currentline = Some(info.currentline);
141+
}
142+
143+
if select.contains(&b'u') {
144+
nups = Some(info.nups);
145+
}
146+
147+
Ok(DebugInfo {
148+
event: info.event,
149+
name,
150+
namewhat,
151+
what,
152+
source,
153+
currentline,
154+
nups,
155+
linedefined,
156+
lastlinedefined,
157+
short_src,
158+
func,
159+
})
160+
}
60161
}
61162

62163
#[macro_export]

packages/autorun-lua/src/lua/raw.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const LUA_IDSIZE: usize = 60;
1111

1212
#[repr(C)]
1313
#[derive(Debug)]
14-
pub struct DebugInfo {
14+
pub struct RawDebugInfo {
1515
pub event: c_int,
1616
pub name: *const c_char, // n
1717
pub namewhat: *const c_char, // n
@@ -239,8 +239,8 @@ impl RawLuaApi {
239239
self._toboolean(state, index) != 0
240240
}
241241

242-
pub fn getinfo(&self, state: *mut LuaState, level: c_int, what: &CStr) -> Option<DebugInfo> {
243-
let mut debug_info = unsafe { std::mem::zeroed::<DebugInfo>() };
242+
pub fn getinfo(&self, state: *mut LuaState, level: c_int, what: &CStr) -> Option<RawDebugInfo> {
243+
let mut debug_info = unsafe { std::mem::zeroed::<RawDebugInfo>() };
244244

245245
if self.getstack(state, level, &raw mut debug_info as _) == 0 {
246246
return None;

packages/autorun-lua/src/value/table.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::{FromLua, Globals, IntoLua, LuaApi, LuaResult, LuaState, RawHandle, RawLuaApi, TryFromLua};
1+
use crate::{
2+
FromLua, Globals, IntoLua, LuaApi, LuaError, LuaResult, LuaState, LuaTypeId, LuaValue, RawHandle, RawLuaApi, TryFromLua,
3+
};
24

35
#[derive(Debug, Clone, Copy)]
46
pub struct LuaTable {
@@ -47,3 +49,12 @@ impl IntoLua for &LuaTable {
4749
lua.push(state, &self.handle);
4850
}
4951
}
52+
53+
impl TryFromLua for LuaTable {
54+
fn try_from_lua(lua: &RawLuaApi, state: *mut LuaState, index: i32) -> LuaResult<Self> {
55+
match lua.to(state, index) {
56+
LuaValue::Table(table) => Ok(table),
57+
other => Err(LuaError::mismatch(LuaTypeId::Table, other.typeid())),
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)