Skip to content

Commit f805be7

Browse files
authored
Merge pull request #57 from thevurv/lua-api-2-pt2-chapter2
Lua api 2 pt2 chapter2
2 parents c86ce7f + 6844445 commit f805be7

File tree

23 files changed

+560
-312
lines changed

23 files changed

+560
-312
lines changed

packages/autorun-env/src/env.rs

Lines changed: 23 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub mod global;
33
use anyhow::Context;
44
use autorun_core::plugins::Plugin;
55
use autorun_log::*;
6-
use autorun_lua::{Globals, LuaApi, LuaTable};
6+
use autorun_lua::{Globals, IntoLua, IntoLuaArgs, LuaApi, LuaFunction, LuaTable, LuaValue, RawLuaApi};
77
use autorun_luajit::{GCRef, LJState, index2adr};
88
use autorun_types::{LuaState, Realm};
99
use std::ffi::{CStr, CString, c_int};
@@ -19,6 +19,12 @@ pub struct EnvHandle {
1919
autorun: LuaTable,
2020
}
2121

22+
impl IntoLua for &EnvHandle {
23+
fn into_lua(self, lua: &RawLuaApi, state: *mut LuaState) {
24+
lua.push(state, &self.env);
25+
}
26+
}
27+
2228
macro_rules! wrap {
2329
($func:expr) => {
2430
autorun_lua::as_lua_function!(|lua: &LuaApi, state: *mut LuaState| {
@@ -33,8 +39,7 @@ macro_rules! wrap {
3339

3440
// todo: potentially add a silenterror type so we can return that and it'll return a nil.
3541
// right now this would kind of leak the fact that it's an autorun function.
36-
lua.push(state, c"");
37-
lua.raw.error(state);
42+
lua.error(state, c"");
3843
} else {
3944
$func(lua, state, env)
4045
}
@@ -43,10 +48,6 @@ macro_rules! wrap {
4348
}
4449

4550
impl EnvHandle {
46-
pub fn push(&self, lua: &LuaApi, state: *mut LuaState) {
47-
lua.push(state, &self.env);
48-
}
49-
5051
pub fn realm(&self) -> Realm {
5152
self.realm
5253
}
@@ -66,26 +67,23 @@ impl EnvHandle {
6667
}
6768

6869
pub fn is_active(&self, lua: &LuaApi, state: *mut LuaState) -> bool {
69-
if lua.raw.getinfo(state, 1, c"f").is_none() {
70-
// No function info available
70+
let Ok(info) = lua.getinfo(state, 1, c"f") else {
7171
return false;
72-
}
72+
};
7373

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

80-
equal
78+
lua.equal(state, &env, &self.env)
8179
}
8280

8381
pub fn get_active_plugin(&self, lua: &LuaApi, state: *mut LuaState) -> Option<&Plugin> {
8482
if !self.is_active(lua, state) {
8583
return None;
8684
}
8785

88-
let dir: *mut Plugin = lua.get(state, &self.autorun, "PLUGIN");
86+
let dir: *mut Plugin = lua.get(state, &self.autorun, "PLUGIN").ok()?;
8987
let dir = unsafe { dir.as_ref() }?;
9088

9189
Some(dir)
@@ -119,11 +117,7 @@ impl EnvHandle {
119117
let name = self.format_chunk_name(name)?;
120118
let chunk = lua.load(state, src, &name)?;
121119
lua.setfenv(state, &chunk, &self.env)?;
122-
123-
lua.push(state, &chunk);
124-
if let Err(why) = lua.raw.pcall(state, 0, 0, 0) {
125-
anyhow::bail!("Failed to execute: {}", why);
126-
}
120+
lua.pcall(state, &chunk, ())?;
127121

128122
Ok(())
129123
}
@@ -136,7 +130,7 @@ impl EnvHandle {
136130
lua.set(state, &env, "_G", Globals);
137131

138132
// todo: refactor luajit code to not depend on the stack
139-
lua.push(state, &env);
133+
lua.raw.push(state, &env);
140134

141135
// Can unwrap since we are sure there is something on the stack
142136
let lj_state = state as *mut LJState;
@@ -174,46 +168,15 @@ impl EnvHandle {
174168
Ok(())
175169
}
176170

177-
pub fn trigger(&self, lua: &LuaApi, state: *mut LuaState, event_name: &CStr, n_args: c_int) -> anyhow::Result<()> {
178-
lua.push(state, event_name);
179-
lua.raw.insert(state, -(n_args + 1));
180-
181-
lua.push(state, &self.autorun);
182-
lua.raw.getfield(state, -1, c"trigger".as_ptr());
183-
lua.raw.remove(state, -2); // remove Autorun table
184-
185-
if lua.raw.typeid(state, -1) != autorun_lua::LuaTypeId::Function {
186-
lua.raw.pop(state, 1);
187-
anyhow::bail!("don't remove Autorun.trigger lil bro.");
188-
}
189-
190-
lua.raw.insert(state, -(n_args + 2));
191-
lua.raw.pcall(state, n_args + 1, 0, 0).map_err(|e| anyhow::anyhow!(e))?;
192-
171+
pub fn trigger(&self, lua: &LuaApi, state: *mut LuaState, args: impl IntoLuaArgs) -> anyhow::Result<()> {
172+
let trigger: LuaFunction = lua.get(state, &self.autorun, "trigger")?;
173+
lua.pcall(state, &trigger, args)?;
193174
Ok(())
194175
}
195176

196-
pub fn run_remote_callbacks(
197-
&self,
198-
lua: &LuaApi,
199-
state: *mut LuaState,
200-
event_name: &CStr,
201-
n_args: c_int,
202-
) -> anyhow::Result<()> {
203-
lua.push(state, event_name);
204-
lua.raw.insert(state, -(n_args + 1));
205-
206-
lua.push(state, &self.autorun);
207-
lua.raw.getfield(state, -1, c"runRemoteCallbacks".as_ptr());
208-
lua.raw.remove(state, -2); // remove Autorun table
209-
210-
if lua.raw.typeid(state, -1) != autorun_lua::LuaTypeId::Function {
211-
lua.raw.pop(state, 1);
212-
anyhow::bail!("don't remove Autorun.runRemoteCallbacks lil bro.");
213-
}
214-
215-
lua.raw.insert(state, -(n_args + 2));
216-
lua.raw.pcall(state, n_args + 1, 0, 0).map_err(|e| anyhow::anyhow!(e))?;
177+
pub fn run_remote_callbacks(&self, lua: &LuaApi, state: *mut LuaState, args: impl IntoLuaArgs) -> anyhow::Result<()> {
178+
let run_remote_callbacks = lua.get(state, &self.autorun, "runRemoteCallbacks")?;
179+
lua.pcall(state, &run_remote_callbacks, args)?;
217180

218181
Ok(())
219182
}

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

Lines changed: 4 additions & 5 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,8 +13,8 @@ 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>() };
17-
let stack_level = lua.to::<i32>(state, 1);
16+
let mut debug_info = unsafe { std::mem::zeroed::<RawDebugInfo>() };
17+
let stack_level = lua.raw.try_to::<i32>(state, 1)?;
1818
lua.raw.pop(state, 1); // remove the stack level argument
1919

2020
if lua.raw.getstack(state, stack_level, &raw mut debug_info as _) == 0 {
@@ -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-env/src/functions/detour.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub fn detour(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> any
3636
anyhow::bail!("Second argument must be a function to use as detour.");
3737
}
3838

39-
let detour_callback = RawHandle::from_stack(lua, state).context("Failed to create raw handle for detour callback.")?;
39+
let detour_callback = RawHandle::from_stack(&lua.raw, state).context("Failed to create raw handle for detour callback.")?;
4040
let mut original_function_ptr = Box::new(0usize);
4141

4242
// create the trampoline
@@ -95,7 +95,7 @@ pub fn copy_fast_function(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHa
9595
let original_ffid = gcfunc.header().ffid;
9696
let original_upvalues = gcfunc.header().nupvalues;
9797

98-
let function_handle = RawHandle::from_stack(lua, state).context("Failed to create raw handle for function.")?;
98+
let function_handle = RawHandle::from_stack(&lua.raw, state).context("Failed to create raw handle for function.")?;
9999

100100
let trampoline = make_detour_trampoline(lua, function_handle.id(), std::ptr::null(), detour_handler)?;
101101
// Not a detour, but we can reuse the trampoline maker to create a fast-function trampoline

packages/autorun-env/src/functions/detour/handlers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub extern "C-unwind" fn detour_handler(
1818
let lua = unsafe { &*lua_api };
1919

2020
let callback_handle = RawHandle::from_id(callback_id);
21-
callback_handle.push(lua, state);
21+
lua.raw.push(state, &callback_handle);
2222
lua.raw.insert(state, 1);
2323

2424
let num_arguments = lua.raw.gettop(state) - 1;

packages/autorun-env/src/functions/detour/userdata.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub struct Detour {
1414
impl LuaUserdata for Detour {}
1515

1616
pub fn detour_enable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<()> {
17-
let detour = lua.to::<*mut Detour>(state, 1);
18-
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
17+
let detour = lua.raw.try_to::<*mut Detour>(state, 1)?;
18+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("Null detour"))?;
1919

2020
unsafe {
2121
detour.detour.enable()?;
@@ -25,8 +25,8 @@ pub fn detour_enable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle)
2525
}
2626

2727
pub fn detour_disable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<()> {
28-
let detour = lua.to::<*mut Detour>(state, 1);
29-
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
28+
let detour = lua.raw.try_to::<*mut Detour>(state, 1)?;
29+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("Null detour"))?;
3030

3131
unsafe {
3232
detour.detour.disable()?;
@@ -36,15 +36,15 @@ pub fn detour_disable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle
3636
}
3737

3838
pub fn detour_get_original(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<LuaCFunction> {
39-
let detour = lua.to::<*mut Detour>(state, 1);
40-
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
39+
let detour = lua.raw.try_to::<*mut Detour>(state, 1)?;
40+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("Null detour"))?;
4141

4242
Ok(unsafe { std::mem::transmute::<usize, LuaCFunction>(*detour.original_function_ptr) })
4343
}
4444

4545
pub fn detour_remove(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<()> {
46-
let detour = lua.to::<*mut Detour>(state, 1);
47-
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
46+
let detour = lua.raw.try_to::<*mut Detour>(state, 1)?;
47+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("Null detour"))?;
4848

4949
unsafe {
5050
detour.detour.disable()?;

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ use autorun_types::LuaState;
33

44
pub fn load(lua: &LuaApi, state: *mut LuaState, env: crate::EnvHandle) -> anyhow::Result<RawLuaReturn> {
55
let source = lua.raw.checkstring(state, 1);
6-
let chunk_name = lua.to::<Option<&[u8]>>(state, 2).unwrap_or(b"loadstring");
6+
let chunk_name = lua.raw.try_to::<Option<&[u8]>>(state, 2)?.unwrap_or(b"loadstring");
77
let chunk_name = std::ffi::CString::new(chunk_name)?;
88
let chunk_name = env.format_chunk_name(&chunk_name)?;
99

10-
if let Err(why) = lua.raw.loadbufferx(state, source.as_bytes(), &chunk_name, c"t") {
11-
lua.raw.pushnil(state);
12-
lua.push(state, why.to_string());
13-
return Ok(RawLuaReturn(2));
10+
match lua.load(state, source.as_bytes(), &chunk_name) {
11+
Err(why) => {
12+
lua.raw.pushnil(state);
13+
lua.raw.push(state, why.to_string());
14+
Ok(RawLuaReturn(2))
15+
}
16+
Ok(chunk) => {
17+
lua.raw.push(state, &chunk);
18+
Ok(RawLuaReturn(1))
19+
}
1420
}
15-
16-
Ok(RawLuaReturn(1))
1721
}

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

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use autorun_lua::LuaApi;
1+
use autorun_lua::{LuaApi, LuaValue};
22
use autorun_types::LuaState;
33

44
pub fn print(lua: &LuaApi, state: *mut LuaState, env: crate::EnvHandle) -> anyhow::Result<()> {
@@ -7,42 +7,29 @@ pub fn print(lua: &LuaApi, state: *mut LuaState, env: crate::EnvHandle) -> anyho
77
let nargs = lua.raw.gettop(state);
88
let mut args = Vec::with_capacity(nargs as usize);
99
for i in 1..=nargs {
10-
match lua.raw.typeid(state, i) {
11-
autorun_lua::LuaTypeId::Nil => {
10+
match lua.raw.to::<LuaValue>(state, i) {
11+
LuaValue::Nil => {
1212
args.push(String::from("nil"));
1313
}
1414

15-
autorun_lua::LuaTypeId::LightUserdata => {
16-
let ptr = lua.raw.touserdata(state, i);
15+
LuaValue::LightUserdata(ptr) => {
1716
args.push(format!("lightuserdata: {:p}", ptr));
1817
}
1918

20-
autorun_lua::LuaTypeId::Userdata => {
21-
let ptr = lua.raw.touserdata(state, i);
19+
LuaValue::Userdata(ptr) => {
2220
args.push(format!("userdata: {:p}", ptr));
2321
}
2422

25-
autorun_lua::LuaTypeId::Function => {
26-
let ptr = lua.raw.tocfunction(state, i);
27-
if let Some(func) = ptr {
28-
args.push(format!("function: {:p}", func));
29-
} else {
30-
args.push(String::from("function: <null>"));
31-
}
23+
LuaValue::CFunction(func) => {
24+
args.push(format!("function: {:p}", func));
3225
}
3326

34-
autorun_lua::LuaTypeId::Thread => {
35-
let ptr = lua.raw.tothread(state, i);
36-
args.push(format!("thread: {:p}", ptr));
37-
}
38-
39-
autorun_lua::LuaTypeId::Boolean => {
40-
let val = lua.to::<bool>(state, i);
27+
LuaValue::Boolean(val) => {
4128
args.push(String::from(if val { "true" } else { "false" }));
4229
}
4330

4431
_ => {
45-
let arg = lua.to::<String>(state, i);
32+
let arg = lua.raw.try_to::<String>(state, i)?;
4633
args.push(arg);
4734
}
4835
}

0 commit comments

Comments
 (0)