Add mlua_derive proc macro module
This commit is contained in:
parent
cade76137a
commit
224ed8ff52
|
@ -13,6 +13,11 @@ license = "MIT"
|
||||||
# [badges]
|
# [badges]
|
||||||
# travis-ci = { repository = "khvzak/mlua", branch = "master" }
|
# travis-ci = { repository = "khvzak/mlua", branch = "master" }
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"mlua_derive",
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = { version = "0.2" }
|
libc = { version = "0.2" }
|
||||||
num-traits = { version = "0.2.6" }
|
num-traits = { version = "0.2.6" }
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "mlua_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Alex Orlenko <zxteam@protonmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
proc-macro2 = "1.0"
|
||||||
|
quote = "1.0"
|
||||||
|
syn = { version = "1.0", features = ["full"] }
|
|
@ -0,0 +1,35 @@
|
||||||
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use proc_macro2::{Ident, Span};
|
||||||
|
use quote::quote_spanned;
|
||||||
|
use syn::{parse_macro_input, spanned::Spanned, AttributeArgs, Error, ItemFn};
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn lua_module(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
let args = parse_macro_input!(attr as AttributeArgs);
|
||||||
|
let item = parse_macro_input!(item as ItemFn);
|
||||||
|
|
||||||
|
if args.len() > 0 {
|
||||||
|
let err = Error::new(Span::call_site(), "the number of arguments must be zero")
|
||||||
|
.to_compile_error();
|
||||||
|
return err.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
let span = item.span();
|
||||||
|
let item_name = item.sig.ident.clone();
|
||||||
|
let ext_entrypoint_name = Ident::new(&format!("luaopen_{}", item.sig.ident), Span::call_site());
|
||||||
|
|
||||||
|
let wrapped = quote_spanned! { span =>
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn #ext_entrypoint_name(state: *mut mlua::lua_State) -> std::os::raw::c_int {
|
||||||
|
#item
|
||||||
|
|
||||||
|
mlua::Lua::init_from_ptr(state)
|
||||||
|
.entrypoint1(#item_name)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
wrapped.into()
|
||||||
|
}
|
18
src/lua.rs
18
src/lua.rs
|
@ -100,6 +100,18 @@ impl Lua {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Executes module entrypoint function, which returns only one Value.
|
||||||
|
// The returned value then pushed to the Lua stack.
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn entrypoint1<'lua, 'callback, R, F>(&'lua self, func: F) -> Result<c_int>
|
||||||
|
where
|
||||||
|
R: ToLua<'callback>,
|
||||||
|
F: 'static + Send + Fn(&'callback Lua) -> Result<R>,
|
||||||
|
{
|
||||||
|
let cb = self.create_callback(Box::new(move |lua, _| func(lua)?.to_lua_multi(lua)))?;
|
||||||
|
unsafe { self.push_value(cb.call(())?).map(|_| 1) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the garbage collector is currently running automatically.
|
/// Returns true if the garbage collector is currently running automatically.
|
||||||
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 }
|
||||||
|
@ -718,8 +730,7 @@ impl Lua {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses 2 stack spaces, does not call checkstack
|
// Uses 2 stack spaces, does not call checkstack
|
||||||
// TODO: return to original
|
pub(crate) unsafe fn push_value(&self, value: Value) -> Result<()> {
|
||||||
pub unsafe fn push_value(&self, value: Value) -> Result<()> {
|
|
||||||
match value {
|
match value {
|
||||||
Value::Nil => {
|
Value::Nil => {
|
||||||
ffi::lua_pushnil(self.state);
|
ffi::lua_pushnil(self.state);
|
||||||
|
@ -770,8 +781,7 @@ impl Lua {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses 2 stack spaces, does not call checkstack
|
// Uses 2 stack spaces, does not call checkstack
|
||||||
// TODO: return to original
|
pub(crate) unsafe fn pop_value(&self) -> Value {
|
||||||
pub unsafe fn pop_value(&self) -> Value {
|
|
||||||
match ffi::lua_type(self.state, -1) {
|
match ffi::lua_type(self.state, -1) {
|
||||||
ffi::LUA_TNIL => {
|
ffi::LUA_TNIL => {
|
||||||
ffi::lua_pop(self.state, 1);
|
ffi::lua_pop(self.state, 1);
|
||||||
|
|
Loading…
Reference in New Issue