Giter Site home page Giter Site logo

khvzak / mlua Goto Github PK

View Code? Open in Web Editor NEW
1.3K 14.0 119.0 2.5 MB

High level Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Roblox Luau bindings to Rust with async/await support

License: Other

Rust 100.00%
rust rust-bindings lua luajit async asynchronous scripting luau wasm

mlua's Introduction

mlua

Build Status Latest Version API Documentation Coverage Status MSRV

Guided Tour | Benchmarks | FAQ

Note

See v0.9 release notes.

mlua is bindings to Lua programming language for Rust with a goal to provide safe (as far as it's possible), high level, easy to use, practical and flexible API.

Started as rlua fork, mlua supports Lua 5.4, 5.3, 5.2, 5.1 (including LuaJIT) and Roblox Luau and allows to write native Lua modules in Rust as well as use Lua in a standalone mode.

mlua tested on Windows/macOS/Linux including module mode in GitHub Actions on x86_64 platform and cross-compilation to aarch64 (other targets are also supported).

WebAssembly (WASM) is supported through wasm32-unknown-emscripten target for all Lua versions excluding JIT.

Usage

Feature flags

mlua uses feature flags to reduce the amount of dependencies, compiled code and allow to choose only required set of features. Below is a list of the available feature flags. By default mlua does not enable any features.

  • lua54: activate Lua 5.4 support
  • lua53: activate Lua 5.3 support
  • lua52: activate Lua 5.2 support
  • lua51: activate Lua 5.1 support
  • luajit: activate LuaJIT support
  • luajit52: activate LuaJIT support with partial compatibility with Lua 5.2
  • luau: activate Luau support (auto vendored mode)
  • luau-jit: activate Luau support with JIT backend.
  • luau-vector4: activate Luau support with 4-dimensional vector.
  • vendored: build static Lua(JIT) library from sources during mlua compilation using lua-src or luajit-src crates
  • module: enable module mode (building loadable cdylib library for Lua)
  • async: enable async/await support (any executor can be used, eg. tokio or async-std)
  • send: make mlua::Lua transferable across thread boundaries (adds Send requirement to mlua::Function and mlua::UserData)
  • serialize: add serialization and deserialization support to mlua types using serde framework
  • macros: enable procedural macros (such as chunk!)
  • parking_lot: support UserData types wrapped in parking_lot's primitives (Arc<Mutex> and Arc<RwLock>)
  • unstable: enable unstable features. The public API of these features may break between releases.

Async/await support

mlua supports async/await for all Lua versions including Luau.

This works using Lua coroutines and require running Thread along with enabling feature = "async" in Cargo.toml.

Examples:

shell command examples:

# async http client (hyper)
cargo run --example async_http_client --features=lua54,async,macros

# async http client (reqwest)
cargo run --example async_http_reqwest --features=lua54,async,macros,serialize

# async http server
cargo run --example async_http_server --features=lua54,async,macros
curl -v http://localhost:3000

Serialization (serde) support

With serialize feature flag enabled, mlua allows you to serialize/deserialize any type that implements serde::Serialize and serde::Deserialize into/from mlua::Value. In addition mlua provides serde::Serialize trait implementation for it (including UserData support).

Example

Compiling

You have to enable one of the features: lua54, lua53, lua52, lua51, luajit(52) or luau, according to the chosen Lua version.

By default mlua uses pkg-config tool to find lua includes and libraries for the chosen Lua version. In most cases it works as desired, although sometimes could be more preferable to use a custom lua library. To achieve this, mlua supports LUA_LIB, LUA_LIB_NAME and LUA_LINK environment variables. LUA_LINK is optional and may be dylib (a dynamic library) or static (a static library, .a archive).

An example how to use them:

my_project $ LUA_LIB=$HOME/tmp/lua-5.2.4/src LUA_LIB_NAME=lua LUA_LINK=static cargo build

mlua also supports vendored lua/luajit using the auxiliary crates lua-src and luajit-src. Just enable the vendored feature and cargo will automatically build and link specified lua/luajit version. This is the easiest way to get started with mlua.

Standalone mode

In a standalone mode mlua allows to add to your application scripting support with a gently configured Lua runtime to ensure safety and soundness.

Add to Cargo.toml :

[dependencies]
mlua = { version = "0.9.7", features = ["lua54", "vendored"] }

main.rs

use mlua::prelude::*;

fn main() -> LuaResult<()> {
    let lua = Lua::new();

    let map_table = lua.create_table()?;
    map_table.set(1, "one")?;
    map_table.set("two", 2)?;

    lua.globals().set("map_table", map_table)?;

    lua.load("for k,v in pairs(map_table) do print(k,v) end").exec()?;

    Ok(())
}

Module mode

In a module mode mlua allows to create a compiled Lua module that can be loaded from Lua code using require. In this case mlua uses an external Lua runtime which could lead to potential unsafety due to unpredictability of the Lua environment and usage of libraries such as debug.

Example

Add to Cargo.toml :

[lib]
crate-type = ["cdylib"]

[dependencies]
mlua = { version = "0.9.7", features = ["lua54", "module"] }

lib.rs :

use mlua::prelude::*;

fn hello(_: &Lua, name: String) -> LuaResult<()> {
    println!("hello, {}!", name);
    Ok(())
}

#[mlua::lua_module]
fn my_module(lua: &Lua) -> LuaResult<LuaTable> {
    let exports = lua.create_table()?;
    exports.set("hello", lua.create_function(hello)?)?;
    Ok(exports)
}

And then (macOS example):

$ cargo rustc -- -C link-arg=-undefined -C link-arg=dynamic_lookup
$ ln -s ./target/debug/libmy_module.dylib ./my_module.so
$ lua5.4 -e 'require("my_module").hello("world")'
hello, world!

On macOS, you need to set additional linker arguments. One option is to compile with cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup, the other is to create a .cargo/config with the following content:

[target.x86_64-apple-darwin]
rustflags = [
  "-C", "link-arg=-undefined",
  "-C", "link-arg=dynamic_lookup",
]

[target.aarch64-apple-darwin]
rustflags = [
  "-C", "link-arg=-undefined",
  "-C", "link-arg=dynamic_lookup",
]

On Linux you can build modules normally with cargo build --release.

On Windows the target module will be linked with lua5x.dll library (depending on your feature flags). Your main application should provide this library.

Module builds don't require Lua lib or headers to be installed on the system.

Publishing to luarocks.org

There is a LuaRocks build backend for mlua modules luarocks-build-rust-mlua.

Modules written in Rust and published to luarocks:

Safety

One of the mlua goals is to provide safe API between Rust and Lua. Every place where the Lua C API may trigger an error longjmp in any way is protected by lua_pcall, and the user of the library is protected from directly interacting with unsafe things like the Lua stack, and there is overhead associated with this safety.

Unfortunately, mlua does not provide absolute safety even without using unsafe . This library contains a huge amount of unsafe code. There are almost certainly bugs still lurking in this library! It is surprisingly, fiendishly difficult to use the Lua C API without the potential for unsafety.

Panic handling

mlua wraps panics that are generated inside Rust callbacks in a regular Lua error. Panics could be resumed then by returning or propagating the Lua error to Rust code.

For example:

let lua = Lua::new();
let f = lua.create_function(|_, ()| -> LuaResult<()> {
    panic!("test panic");
})?;
lua.globals().set("rust_func", f)?;

let _ = lua.load(r#"
    local status, err = pcall(rust_func)
    print(err) -- prints: test panic
    error(err) -- propagate panic
"#).exec();

unreachable!()

Optionally mlua can disable Rust panics catching in Lua via pcall/xpcall and automatically resume them across the Lua API boundary. This is controlled via LuaOptions and done by wrapping the Lua pcall/xpcall functions on a way to prevent catching errors that are wrapped Rust panics.

mlua should also be panic safe in another way as well, which is that any Lua instances or handles remains usable after a user generated panic, and such panics should not break internal invariants or leak Lua stack space. This is mostly important to safely use mlua types in Drop impls, as you should not be using panics for general error handling.

Below is a list of mlua behaviors that should be considered a bug. If you encounter them, a bug report would be very welcome:

  • If you can cause UB with mlua without typing the word "unsafe", this is a bug.

  • If your program panics with a message that contains the string "mlua internal error", this is a bug.

  • Lua C API errors are handled by longjmp. All instances where the Lua C API would otherwise longjmp over calling stack frames should be guarded against, except in internal callbacks where this is intentional. If you detect that mlua is triggering a longjmp over your Rust stack frames, this is a bug!

  • If you detect that, after catching a panic or during a Drop triggered from a panic, a Lua or handle method is triggering other bugs or there is a Lua stack space leak, this is a bug. mlua instances are supposed to remain fully usable in the face of user generated panics. This guarantee does not extend to panics marked with "mlua internal error" simply because that is already indicative of a separate bug.

Sandboxing

Please check the Luau Sandboxing page if you are interested in running untrusted Lua scripts in controlled environment.

mlua provides Lua::sandbox method for enabling sandbox mode (Luau only).

License

This project is licensed under the MIT license

mlua's People

Contributors

acrisci avatar attila-lin avatar aymen-hakim avatar bytedream avatar eatradish avatar estokes avatar getong avatar hack3ric avatar hybrideidolon avatar jhasse avatar jonas-schievink avatar jqnatividad avatar kaikalii avatar khvzak avatar kyren avatar lightsing avatar norlock avatar polachok avatar rise0chen avatar sakridge avatar sondr3 avatar tari avatar tarik02 avatar thelearnerofcode avatar timidger avatar virtusense-trisha avatar wez avatar zh-jq-b avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mlua's Issues

windows module lua5.1 Compilation fails

MSVC with LUA_INC / LUA_LIB / LUA_LIB_NAME environment variables. Windows 10 ,mlua 5.0.1 I set up,but faild. Can you give a more detailed example or configuration

why i can require('ffi') , And i compile it with features 'luajit', luajit source code contain ffi model

local ffi = require("ffi")
ffi.cdef[[
void Sleep(int ms);
int poll(struct pollfd *fds, unsigned long nfds, int timeout);
]]
--  do something...

it report an error about ffi model not exists.

who can help me? thank you

see: http://luajit.org/extensions.html


i check it again,not only ffi model have problem,

thread and debug hanve the same problem too.

you see...:

屏幕截图 2021-03-10 213315

left is jit c code right is lua code in rust, and below is error.

Feature request: 32bit support

I'm in a unique situation where I need to compile Lua source to Lua 32bit binary code to send off to an embedded device. I've proven the technique works but it requires a 32bit Lua implementation on the host machine as well.

To fix this requires simply adding the C define LUA_32BITS from the lua-src crate. From what I understand, I think we would have to pass the feature flag to enable that from this crate.

Is it doable?

Static vendored linkage on Windows

For the sake of developer convenience, I would like to be able to compiled a vendored lua or luajit lib under Windows as a static library. This spares the complexity of setting up the build environment to include the Lua library under Windows, which is the primary development OS for my project as it specifically supports a Windows-only application. However, it doesn't seem either of the source crates support building in this way on Windows.

What would be necessary to add static vendoring support to these crates?

Edit: for context, this is an app using the Lua VM directly, not a C extension module. It is not entirely clear from the documentation if this is already supported or not.

Interoperability between Rust Fn and mlua Function

Hello, I'm writing a library for use in an app that I'd like to be able to extend in Rust and in Lua.

I have an Action struct that stores a function pointer and some metadata (but could be made to use Fn/FnMut instead), and I'd like to be able to construct actions ergonomically from Lua as well.

Here's the Action struct (this uses derive_builder, &str->String conversion code omitted for brevity):

#[derive(Builder, Clone, Default, Getters)]
#[builder(default)
pub struct Action {
    name: String,
    description: String,
    health_added: i64,
    cost: i64,
    #[builder(setter(strip_option))]
    action: Option<fn(&mut Player, &mut Player)>,
}

I'd like to be able to construct actions from Lua like this:

local a = action {
    name = "Test",
    description = "Testing",
    health_added = 2,
    cost = 3,
    action = function(self, other) end
}

And here's my attempt at a Lua constructor:

    let action_constructor = lua.create_function(|_, arguments: Table| {
        let ret = ActionBuilder::default();

        if let Value::String(name) = arguments.get("name")? {
            ret.name(name.to_str()?);
        }
        if let Value::String(description) = arguments.get("description")? {
            ret.description(description.to_str()?);
        }
        if let Value::Integer(health_added) = arguments.get("health_added")? {
            ret.health_added(health_added);
        }
        if let Value::Integer(cost) = arguments.get("cost")? {
            ret.cost(cost.into());
        }
        if let Value::Function(action) = arguments.get("action")? {
            ret.action(action);
        }

        Ok(ret.build())
    })?;

As expected, compilation fails with the following error:

  --> src/scripting.rs:44:24
   |
44 |             ret.action(action);
   |                        ^^^^^^ expected fn pointer, found struct `mlua::function::Function`
   |
   = note: expected fn pointer `for<'r, 's> fn(&'r mut player::Player, &'s mut player::Player)`
                  found struct `mlua::function::Function<'_>`

And from a quick look at the docs and source code for mlua::Function it seems like switching my code to Fn/FnMut won't help either as the former can't be converted into the latter.

So, is there anything I can do to make this work apart from using mlua::Function internally in my rust program instead of Rust Fns or function pointers? I'd prefer Lua to be an optional feature, so that if the user doesn't need to dynamically add actions they can opt out of it.

meet a core dumped

hello, I have met a coredump as following. Maybe it is because I have created to much userdatas. Do you have some idea? Thank you!

thread '' panicked at 'mlua internal error: cannot create a Lua reference, out of auxiliary stack space (this is a bug, please file an issue)', component/luaext/src/lua.rs:2104:17
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
thread '' panicked at 'mlua internal error: extra is poisoned (this is a bug, please file an issue): "PoisonError { inner: .. }"', component/luaext/src/lua.rs:1454:29
stack backtrace:
0: 0x7f07ed6d14a5 - backtrace::backtrace::libunwind::trace::h14d338b30b3ea0a7
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
1: 0x7f07ed6d14a5 - backtrace::backtrace::trace_unsynchronized::h73ea91d74a3fd67f
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
2: 0x7f07ed6d14a5 - std::sys_common::backtrace::_print_fmt::hd42948c952866e12
at src/libstd/sys_common/backtrace.rs:78
3: 0x7f07ed6d14a5 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::ha8f928866ff7571e
at src/libstd/sys_common/backtrace.rs:59
4: 0x7f07ed6f871c - core::fmt::write::he0c1e5f7426d2718
at src/libcore/fmt/mod.rs:1076
5: 0x7f07ed6cb682 - std::io::Write::write_fmt::hf3afc6cfd57d0033
at src/libstd/io/mod.rs:1537
6: 0x7f07ed6d3950 - std::sys_common::backtrace::_print::hfc0110703f3696fd
at src/libstd/sys_common/backtrace.rs:62
7: 0x7f07ed6d3950 - std::sys_common::backtrace::print::h3f77c6990ddfaa22
at src/libstd/sys_common/backtrace.rs:49
8: 0x7f07ed6d3950 - std::panicking::default_hook::{{closure}}::heae49580a8d62d75
at src/libstd/panicking.rs:198
9: 0x7f07ed6d369c - std::panicking::default_hook::hecc34e3f729e213c
at src/libstd/panicking.rs:217
10: 0x7f07ed6d3f93 - std::panicking::rust_panic_with_hook::he82f5d0644692441
at src/libstd/panicking.rs:526
11: 0x7f07ed6d3b8b - rust_begin_unwind
at src/libstd/panicking.rs:437
12: 0x7f07ed6f63a1 - core::panicking::panic_fmt::h09c929f06bb87c98
at src/libcore/panicking.rs:85
13: 0x7f07ed6f61c3 - core::option::expect_none_failed::h188f17af6c9f404b
at src/libcore/option.rs:1269
14: 0x7f07ecaf7f51 - core::result::Result<T,E>::expect::h4cf2418c3e8bd2c0
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/result.rs:963
15: 0x7f07ecafeaee - ace_lua::lua::Lua::drop_ref::hd935e4db600d09c0
at component/luaext/src/lua.rs:1454
16: 0x7f07ecb1571e - <ace_lua::types::LuaRef as core::ops::drop::Drop>::drop::h619b39f8a232d124
at component/luaext/src/types.rs:110
17: 0x7f07ecb136de - core::ptr::drop_in_place::h9df41a43ab662568
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ptr/mod.rs:184
18: 0x7f07ecb13aae - core::ptr::drop_in_place::ha5397b537a1a39c1
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ptr/mod.rs:184
19: 0x7f07ecb132a2 - core::ptr::drop_in_place::h785258ef8faacc0c
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ptr/mod.rs:184
20: 0x7f07ecb1309b - core::ptr::drop_in_place::h6236c5a9aa1ef764
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ptr/mod.rs:184
21: 0x7f07ecb144e2 - <alloc::vec::Vec as core::ops::drop::Drop>::drop::h4191162f6adbc1ab
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/liballoc/vec.rs:2423
22: 0x7f07ecb14252 - core::ptr::drop_in_place::hf4ff8d7e5417ce91
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ptr/mod.rs:184
23: 0x7f07ecb12a7e - core::ptr::drop_in_place::h2bfa4746821c31f8
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ptr/mod.rs:184
24: 0x7f07ecacac79 - ace_lua::lua::Lua::create_callback::call_callback::{{closure}}::h2edc225d6e372c02
at component/luaext/src/lua.rs:1575
25: 0x7f07ecab8675 - ace_lua::util::callback_error::{{closure}}::hd1b215439405bd26
at component/luaext/src/util.rs:416
26: 0x7f07ecabac1b - <std::panic::AssertUnwindSafe as core::ops::function::FnOnce<()>>::call_once::had2cbfd8f971a3a1
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panic.rs:318
27: 0x7f07ecb0d62d - std::panicking::try::do_call::h2d88971dae4041f1
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panicking.rs:348
28: 0x7f07ecb0e6bd - __rust_try
29: 0x7f07ecb0c4f5 - std::panicking::try::h8461a0ed33833dbb
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panicking.rs:325
30: 0x7f07ecabae2a - std::panic::catch_unwind::h1d0cc861e6836fc8
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panic.rs:394
31: 0x7f07ecab4317 - ace_lua::util::callback_error::h0eaea63ccc78c9c4
at component/luaext/src/util.rs:416
32: 0x7f07ecaff082 - ace_lua::lua::Lua::create_callback::call_callback::ha5ae2a32af06bace
at component/luaext/src/lua.rs:1545
33: 0x41b736 -
34: 0x7f07ecae1375 - ace_lua::util::init_userdata_metatable::meta_index_impl::ha996786ee8aac20a
at component/luaext/src/util.rs:327
35: 0x41b736 -
36: 0x40b100 - lua_pcall
37: 0x7f07ecb206f8 - ace_lua::function::Function::call::h38687ef803d6db9b
at component/luaext/src/function.rs:76
38: 0x7f07eca88891 - ace_lua::luabind::object_wrapper::set_create_addr_func::{{closure}}::h3d35f1e41b2f3e18
at component/luaext/src/luabind/object_wrapper.rs:132
39: 0x7f07ecd2f9c4 - libobjserv::txn::coordinator::Coordinator::create_object::h28d5f32055b9a30b
at objserv/src/txn/coordinator.rs:588
40: 0x7f07ecc4e7c1 - libobjserv::proxy::txn_global_proxy::TxnGlobalProxy::create_object::hc0116bdfc27d4c69
at objserv/src/proxy/txn_global_proxy.rs:19
41: 0x7f07ecaf2125 - ace_lua::luabind::object_proxy_wrapper::global_create_object::h73b3e65abbed5b40
at component/luaext/src/luabind/object_proxy_wrapper.rs:114
42: 0x7f07ecb0fd39 - core::ops::function::Fn::call::h9fc8867d178fbb90
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ops/function.rs:72
43: 0x7f07ecabe992 - ace_lua::lua::Lua::create_function::{{closure}}::hbd7101109b94417e
at component/luaext/src/lua.rs:852
44: 0x7f07eca94744 - <alloc::boxed::Box as core::ops::function::Fn>::call::h42685aeb59d5cd73
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/liballoc/boxed.rs:1095
45: 0x7f07ecaca5cb - ace_lua::lua::Lua::create_callback::call_callback::{{closure}}::h2edc225d6e372c02
at component/luaext/src/lua.rs:1566
46: 0x7f07ecab8675 - ace_lua::util::callback_error::{{closure}}::hd1b215439405bd26
at component/luaext/src/util.rs:416
47: 0x7f07ecabac1b - <std::panic::AssertUnwindSafe as core::ops::function::FnOnce<()>>::call_once::had2cbfd8f971a3a1
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panic.rs:318
48: 0x7f07ecb0d62d - std::panicking::try::do_call::h2d88971dae4041f1
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panicking.rs:348
49: 0x7f07ecb0e6bd - __rust_try
50: 0x7f07ecb0c4f5 - std::panicking::try::h8461a0ed33833dbb
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panicking.rs:325
51: 0x7f07ecabae2a - std::panic::catch_unwind::h1d0cc861e6836fc8
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panic.rs:394
52: 0x7f07ecab4317 - ace_lua::util::callback_error::h0eaea63ccc78c9c4
at component/luaext/src/util.rs:416
53: 0x7f07ecaff082 - ace_lua::lua::Lua::create_callback::call_callback::ha5ae2a32af06bace
at component/luaext/src/lua.rs:1545
54: 0x41b736 -
55: 0x40b100 - lua_pcall
56: 0x7f07ecb228e9 - ace_lua::function::Function::call::hcc55091a5af7731a
at component/luaext/src/function.rs:76
57: 0x7f07ecafb4ff - ace_lua::luabind::global_wrapper::global_register_root_transaction::{{closure}}::h429bae576c621b10
at component/luaext/src/luabind/global_wrapper.rs:29
58: 0x7f07ecb6175f - libobjserv::txn::transaction_manager::TransactionManager::start_root_transaction::{{closure}}::hd876b3012dca3fb7
at objserv/src/txn/transaction_manager.rs:159
59: 0x7f07ecb3e958 - libobjserv::txn::transaction::Transaction::run::h298c91517bcb4b40
at objserv/src/txn/transaction.rs:289
60: 0x7f07ecdfa1a3 - libobjserv::txn::txn_execute::start_transaction::{{closure}}::hebe34dd80880b353
at objserv/src/txn/txn_execute.rs:72
61: 0x7f07ecc87649 - core::ops::function::FnOnce::call_once::h22d2bb6a6dcabe5c
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ops/function.rs:233
62: 0x7f07ecc867be - core::ops::function::FnOnce::call_once{{vtable.shim}}::hc77f51f7dbda7d96
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ops/function.rs:233
63: 0x7f07ed54f9e8 - <alloc::boxed::Box as core::ops::function::FnOnce>::call_once::h7752ffb74ed63146
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/liballoc/boxed.rs:1081
64: 0x7f07ed07f074 - ace_execute::timer::ExecuteManager::process::hf06db2fe966532c5
at component/execute/src/timer.rs:79
65: 0x7f07ecb60c2f - libobjserv::txn::txn_execute::TxnExecuteManager::update::h5e215d161b9ace28
at objserv/src/txn/txn_execute.rs:41
66: 0x7f07ecb603f1 - libobjserv::server::server::Server::update::h49e556cbfd3b888f
at objserv/src/server/server.rs:88
67: 0x7f07ecaf366a - ace_lua::luabind::global_wrapper::global_update::hac6823f7c43e7aab
at component/luaext/src/luabind/global_wrapper.rs:67
68: 0x7f07ecb0feaf - core::ops::function::Fn::call::he9f51a367db42a32
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/ops/function.rs:72
69: 0x7f07ecabe07a - ace_lua::lua::Lua::create_function::{{closure}}::ha068ef3854d4b54f
at component/luaext/src/lua.rs:852
70: 0x7f07eca94744 - <alloc::boxed::Box as core::ops::function::Fn>::call::h42685aeb59d5cd73
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/liballoc/boxed.rs:1095
71: 0x7f07ecaca5cb - ace_lua::lua::Lua::create_callback::call_callback::{{closure}}::h2edc225d6e372c02
at component/luaext/src/lua.rs:1566
72: 0x7f07ecab8675 - ace_lua::util::callback_error::{{closure}}::hd1b215439405bd26
at component/luaext/src/util.rs:416
73: 0x7f07ecabac1b - <std::panic::AssertUnwindSafe as core::ops::function::FnOnce<()>>::call_once::had2cbfd8f971a3a1
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panic.rs:318
74: 0x7f07ecb0d62d - std::panicking::try::do_call::h2d88971dae4041f1
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panicking.rs:348
75: 0x7f07ecb0e6bd - __rust_try
76: 0x7f07ecb0c4f5 - std::panicking::try::h8461a0ed33833dbb
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panicking.rs:325
77: 0x7f07ecabae2a - std::panic::catch_unwind::h1d0cc861e6836fc8
at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/panic.rs:394
78: 0x7f07ecab4317 - ace_lua::util::callback_error::h0eaea63ccc78c9c4
at component/luaext/src/util.rs:416
79: 0x7f07ecaff082 - ace_lua::lua::Lua::create_callback::call_callback::ha5ae2a32af06bace
at component/luaext/src/lua.rs:1545
80: 0x41b736 -
81: 0x40b100 - lua_pcall
82: 0x403ccc -
83: 0x404abe -
84: 0x41b736 -
85: 0x40b17a - lua_cpcall
86: 0x403804 - main
87: 0x7f07edd10830 - __libc_start_main
88: 0x403879 - _start
89: 0x0 -
thread panicked while panicking. aborting.
Illegal instruction (core dumped)

Special behavior around debug library?

Hello,
I have created a simple mlua program,
I am installing with cargo.toml line
mlua = {version="0.5.1", features=["luajit", "vendored"]}
The library is very good but there is one weird thing, the debug library normally available as the object debug in the lua namespace is not present.
We use this to display stacktraces.
With the LuaJIT we embed in our C version debug is just present, I don't think we had to do anything special.

Is there special behavior with the debug library in mlua? Is this intentional?
Are there other "standard" Lua libraries which mlua emits in its vendored luajit version?

I see an ambiguous note in the mlua README about "usage of libraries such as debug" but I do not understand this and I don't see anything special in the docs.rs page (I see the Debug object but it is the lua interface I'm interested in).

"Expected behavior": If there is special behavior around debug (or other normally present libraries) in mlua compared to normal lua distributions, or there is something special we have to do to access debug, it should be in the documentation.

Thanks!

[Question] variable lifetimes and borrowing

this is what I have:

use mlua::{Function, Lua, Result, UserData, UserDataMethods};

// not really usefull but I wanted to use a struct here
struct Number {val : i32}
impl UserData for &Number{
    fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
        methods.add_method("is_positive", |_, this, _: ()| {
            Ok(this.val >= 0)
        });
    }
}


fn is_positive(lua: &Lua, n: &Number) -> Result<bool>{ // <-- borrow n
    
    let script : Function = lua.load(r#"#
                function(i)
                    if i:is_positive() then
                        return true
                    else 
                        return false
                    end
            "#).eval()?;
    script.call::<_, bool>(n) // Here it says lifetime `'static` required
    
}
fn main() {
    let lua = Lua::new();
    let a_number = Number {val : 2};
    is_positive(&lua, &a_number); // <-- where the variable comes from

    // Still need a_number here
    ...

}

Now I read that you can only pass types with static lifetimes to lua so is it not possible to keep a_number after calling is_positive without making it static? If I for example don't use that borrow the code compiles. But again, I want to keep a_number.

I also tried scope but it still gives me the 'static lifetime issue.

Error building against luajit

My system (Arch Linux) has luajit-2.0.5 (the latest stable release). The system's Neovim package is also compiled against that, so the building Lua interpreter is luajit.

I'm able to build a module that can be loaded by Lua 5.3, but I'm having a hard time building the same source against luajit so it can be loaded by Neovim.

❯ LUA_INC=/usr/include/luajit-2.0 LUA_LIB=/usr/share/luajit-2.0.5 LUA_LIB_NAME=luajit LUA_LINK=static cargo build
   Compiling mlua v0.3.2
error[E0432]: unresolved import `self::lualib::LUA_UTF8LIBNAME`
   --> /home/caleb/.cargo/registry/src/github.com-1ecc6299db9ec823/mlua-0.3.2/src/ffi/mod.rs:230:9
    |
230 | pub use self::lualib::LUA_UTF8LIBNAME;
    |         ^^^^^^^^^^^^^^---------------
    |         |             |
    |         |             help: a similar name exists in the module: `LUA_STRLIBNAME`
    |         no `LUA_UTF8LIBNAME` in `ffi::lualib`

error[E0432]: unresolved import `super::glue::LUAL_NUMSIZES`
  --> /home/caleb/.cargo/registry/src/github.com-1ecc6299db9ec823/mlua-0.3.2/src/ffi/lauxlib.rs:32:9
   |
32 | pub use super::glue::LUAL_NUMSIZES;
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `LUAL_NUMSIZES` in `ffi::glue`

error[E0432]: unresolved import `super::glue::LUAL_NUMSIZES`
  --> /home/caleb/.cargo/registry/src/github.com-1ecc6299db9ec823/mlua-0.3.2/src/ffi/luaconf.rs:34:9
   |
34 | pub use super::glue::LUAL_NUMSIZES;
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `LUAL_NUMSIZES` in `ffi::glue`

error[E0432]: unresolved import `super::glue::LUA_UTF8LIBNAME`
  --> /home/caleb/.cargo/registry/src/github.com-1ecc6299db9ec823/mlua-0.3.2/src/ffi/lualib.rs:36:9
   |
36 | pub use super::glue::LUA_UTF8LIBNAME;
   |         ^^^^^^^^^^^^^---------------
   |         |            |
   |         |            help: a similar name exists in the module: `LUA_STRLIBNAME`
   |         no `LUA_UTF8LIBNAME` in `ffi::glue`

error: aborting due to 4 previous errors

Is it possible to build against this version of luajit or is this completely unsupported?

A few questions I have related to including external libraries

Hello!

First of all I want to really thank you for this awesome library!

How would you go about including libuv inside the executable?
How would you go about including custom lua scripts (something like the neovim runtime) inside the executable?

Vendored LuaJIT cross-compilation fails: "Relocation R_AARCH64_ADR_PREL_PG_HI21 against external symbol `stdin@@GLIBC_2.17' can not be used when making a shared object; recompile with -fPIC"

Trying to cross-compile mlua with vendored LuaJIT to aarch64-unknown-linux-gnu fails with the error:

          /usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: /tmp/rustcaPL0YP/libmlua-cede66d99741786d.rlib(lj_load.o)(.text+0x318): unresolvable R_AARCH64_ADR_PREL_PG_HI21 relocation against symbol `stdin@@GLIBC_2.17'
          /usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: final link failed: Bad value
          collect2: error: ld returned 1 exit status

This happens on any combination of toolchains: clang, gcc, gcc using cross build

Full compilation error (warning: big)
  = note: "aarch64-linux-gnu-gcc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-Wl,--eh-frame-hdr" "-L" "/rust/lib/rustlib/aarch64-unknown-linux-gnu/lib" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.4bwo0gqzzle6r69j.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.5gfjyx3vp8qcby3m.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.addr2line-ab4907804cc31b6a.addr2line.9mz01pp9-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.addr2line-d938c05cbf271d47.addr2line.a24ah5fo-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.adler-073e727127f3a79a.adler.6peljd97-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.adler-3845b3800267ae8c.adler.2p69y2si-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.aho_corasick-3d5af6ba0118ee51.aho_corasick.f1x2h3ut-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.alloc-55cbf548fbeff055.alloc.9c3vo4yn-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.async_channel-131735bf57d424a0.async_channel.6xbm5alj-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.async_stream-1ea2a36e7449a299.async_stream.86b90qtf-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.atty-7446fe421bb17c2c.atty.2vkzw9an-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.backtrace-b36b330ffcd55382.backtrace.58p6upwq-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.bitflags-5265f99f3e6aa768.bitflags.1zxv1szi-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.bstr-c8996fdd1d7996a9.bstr.7dyz95gm-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.bytes-f3918d182adcd75f.bytes.egi7b3z4-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.cache_padded-2655f97d20632e09.cache_padded.9iwv5o20-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.cfg_if-16b9980f23716719.cfg_if.2jp8i24n-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.cfg_if-26d4eceb284ee462.cfg_if.7dvedn28-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.cfg_if-ceb1eea30bd6972a.cfg_if.7pr16ylt-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.clap-b0ebf571b08c21f1.clap.2xf1ff73-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.color_eyre-7ac8ee01facc7e41.color_eyre.3ceytb9f-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.color_spantrace-188efde27f13ba3e.color_spantrace.eq19zc5k-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.concurrent_queue-be0721d3c0675fd3.concurrent_queue.aro3xxmx-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.core-6c113c0c183f3f13.core.dw0kngoa-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.dashmap-185f7e29995f3f03.dashmap.bf1ycbrt-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.erased_serde-a8ca3f600d82dda6.erased_serde.496oycaw-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.event_listener-b3cf4fe5cc18a352.event_listener.n3bfl17g-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.eyre-601cbd610fea710e.eyre.cxdez3y5-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.fnv-f916d723a169a2a8.fnv.wiv3lrpu-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.futures_channel-e2baed9b8a03fb79.futures_channel.4evv2uqw-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.futures_core-84be788e2ab0c7bf.futures_core.1wyvnaft-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.futures_sink-1913c6ce2f78ecce.futures_sink.6w1f4uqy-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.futures_task-2062bee905bec564.futures_task.a8mslg7l-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.futures_util-26a4ce8bbf74169d.futures_util.6fsgr6r2-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.getrandom-45e13f03d0b9999e.getrandom.5lihbg6v-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.getrandom-46d5f1a6f1383f61.getrandom.35tf94ov-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.gimli-c892d6ceb573f38f.gimli.bwexq1j1-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.gimli-f6af9f8dfd8bc9ad.gimli.5ieyqp7q-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.globset-3cb742cf2838579e.globset.8thygsmr-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.h2-61cb1ddefbd7565f.h2.3bt556wd-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.hashbrown-225cdda79c9dcdab.hashbrown.b5wavk0a-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.hashbrown-bb11f2425839250b.hashbrown.4q3ndfvy-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.http-3e9bf7ad2dcc3152.http.5ccf9r7j-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.http_body-7f7bb330d51bc9c0.http_body.7taagw1i-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.httparse-b2bf1bbe7c52e1f2.httparse.ctrjk3pw-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.httpdate-8af700af740b2c87.httpdate.5lbbgrft-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.hyper-be7002e7aa067a0d.hyper.1onfppst-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.indenter-42eb2f05a3ef2617.indenter.7mcrz6ah-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.indexmap-c234bd12f706b9b4.indexmap.2bucu5lg-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.instant-b8705ab5302c0318.instant.802pf6wh-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.inventory-e24cf0c97d967d22.inventory.8n64a0h0-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.itoa-82df46e41e491c97.itoa.ehmxgv9e-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.lazy_static-935a1dcce40312bd.lazy_static.anc783sq-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.libc-e6d2955b5fc0097d.libc.88rtaak0-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.libc-fc15488178b23d9c.libc.4fat4fll-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.lock_api-bcd0c0c94fe3bdae.lock_api.clspvh70-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.log-5ae67e8e93dda5f1.log.11kf11ru-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.memchr-905eb635e7424680.memchr.bidq8fsy-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.miniz_oxide-31227c973d1375e4.miniz_oxide.98p5hpq9-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.miniz_oxide-8f7ee3a66d5263a2.miniz_oxide.8olm6mvo-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.mio-ba4f00c40b4e79ba.mio.bqfu9joo-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.mlua-cede66d99741786d.mlua.a09pdpwi-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.num_cpus-bba5349f180a2988.num_cpus.1yy78hpo-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.num_traits-7bb4d1a9e2b3be0a.num_traits.etruu306-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.object-5649783032f394ad.object.2xrz4qre-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.object-ae7382c239f27065.object.6i1561hw-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.once_cell-a3c680d021675703.once_cell.68lq3y1r-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.os_str_bytes-98a65368b922fdd6.os_str_bytes.e1rzk4gc-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.owo_colors-b723cc292dd6903c.owo_colors.5fau3w4m-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.panic_unwind-a4d8cb8695e99ca2.panic_unwind.9lo24dps-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.parking_lot-6a68ac8a9cf59ce5.parking_lot.9nuzk7is-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.parking_lot_core-cb1d137011228a87.parking_lot_core.d4c4ldk8-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.pin_project-594caeb3066c51fc.pin_project.1y3fljap-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.pin_project-c9806020274932ff.pin_project.7b67byjh-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.pin_project_lite-7be9fa43b21e7f67.pin_project_lite.eqc51gid-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.pin_utils-3492e980379b1638.pin_utils.dj8chpc7-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.ppv_lite86-ee021209f01abb2d.ppv_lite86.5ck36hzj-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rand-42409f537071fffb.rand.ajmyw9bd-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rand-7bd252f4f416387b.rand.2o2zrll7-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rand_chacha-89127099e8d636f5.rand_chacha.d8zy757j-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rand_chacha-a464ecaf595028f5.rand_chacha.6528oa75-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rand_core-a1dd078a195a3b61.rand_core.95wsz17r-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rand_core-c22a9301791804c0.rand_core.eqip3tx1-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rand_distr-e531d933703feaea.rand_distr.drs3cors-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.regex-a092fc87a1b0cc3d.regex.c4g097fe-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.regex_syntax-3a629ca4691c436c.regex_syntax.8a932d9s-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rustc_demangle-0f37b400e190495f.rustc_demangle.p0jr1y79-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rustc_demangle-11099ac2cbd8ce76.rustc_demangle.f2koj6ac-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rustc_std_workspace_alloc-6ea4e18b234faf5b.rustc_std_workspace_alloc.12a3cy6u-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.rustc_std_workspace_core-e841a26a80a43f98.rustc_std_workspace_core.8wx0584m-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.scopeguard-8a27a5619d5b333c.scopeguard.4bpirzce-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.serde-062a1fe31f45a17e.serde.acnxqdlv-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.sharded_slab-f690d3ad884e65fd.sharded_slab.1jczy64y-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.signal_hook_registry-04754e0d75f5297f.signal_hook_registry.exwfh27y-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.slab-0b8395d69f250c91.slab.cx2i8s07-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.smallvec-1529bc8397ddf529.smallvec.cymih5kx-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.socket2-6c387be82f1d30f1.socket2.48o6mhvj-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.static_assertions-3042d7897c30c3cc.static_assertions.4tu0xyca-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.std-5b1d7b96931a3aa7.std.mksz6t53-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.strsim-053e64dc55a4d55b.strsim.1xxb4kym-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.termcolor-13dcfe6b8e1cb8ed.termcolor.38p94mlf-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.textwrap-b7c78596ea0cae43.textwrap.95etjmdi-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.thread_local-a334f0e835e48752.thread_local.6t3pa1qj-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tokio-d02cf1db14bf2dbe.tokio.4okpwbo9-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tokio_stream-4f2e392e482eeff6.tokio_stream.cbollejv-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tokio_util-b964856f4b669c85.tokio_util.dp9wy1p6-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tower_service-fc0e2ee12897bbb3.tower_service.db2w07bc-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tracing-865abf6302930cd6.tracing.32556eny-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tracing_core-4547aa58badbcda5.tracing_core.6dgfns5r-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tracing_error-c13fd4f5428f60a6.tracing_error.3g8nsups-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tracing_futures-874e06cd972d1e1d.tracing_futures.6i5pz3xz-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.tracing_subscriber-37c96eb0d57b7c42.tracing_subscriber.grka5qt8-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.try_lock-b4e63494fc017893.try_lock.ai9kopcc-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.twox_hash-fd242cdc60f7d102.twox_hash.8ihygzrt-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.unicode_width-23eeb90397377339.unicode_width.7fve5zp1-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.unwind-691f83b6be462127.unwind.dwicj4jc-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.vec_map-a4519c5d620f2fed.vec_map.b2z54ax8-cgu.0.rcgu.o.rcgu.o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf.want-302bd40c4965f03b.want.4s3b97dn-cgu.0.rcgu.o.rcgu.o" "-o" "/target/aarch64-unknown-linux-gnu/release/deps/sws-ae0de5f3e9297bdf" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs" "-L" "/target/aarch64-unknown-linux-gnu/release/deps" "-L" "/target/release/deps" "-L" "/target/aarch64-unknown-linux-gnu/release/build/ring-96fd65fe855be798/out" "-L" "/target/aarch64-unknown-linux-gnu/release/build/mlua-2bdf6af1b7b01e02/out/luajit-build/lib" "-L" "/rust/lib/rustlib/aarch64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/tmp/rustcaPL0YP/libmlua-cede66d99741786d.rlib" "-Wl,--start-group" "-Wl,--end-group" "/rust/lib/rustlib/aarch64-unknown-linux-gnu/lib/libcompiler_builtins-dedf96718b1b5f55.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-lutil"
  = note: /usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: /tmp/rustcaPL0YP/libmlua-cede66d99741786d.rlib(lj_load.o): relocation R_AARCH64_ADR_PREL_PG_HI21 against external symbol `stdin@@GLIBC_2.17' can not be used when making a shared object; recompile with -fPIC
          /usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: /tmp/rustcaPL0YP/libmlua-cede66d99741786d.rlib(lj_load.o)(.text+0x318): unresolvable R_AARCH64_ADR_PREL_PG_HI21 relocation against symbol `stdin@@GLIBC_2.17'
          /usr/lib/gcc-cross/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/bin/ld: final link failed: Bad value
          collect2: error: ld returned 1 exit status

LuaJIT should support ARM64, so this seems to be a problem with the vendored compilation. Using a non-JIT lua (such as the feature lua52) does not have this issue.

How to reproduce:

  1. Make a project with vendored LuaJIT
[dependencies]
mlua = { version = "0.5", features = ["luajit", "vendored"] }
  1. Try to cross-compile: cross build --target aarch64-unknown-linux-gnu

  2. Error.

new_with causes Lua 5.4 to panic

I seem to have found an odd bug with new_with that causes mlua to panic. Attempting to disable part of the standard library causes the program to panic.

use ::mlua::{Lua, StdLib};

fn main() {
	let state = Lua::new_with(StdLib::MATH);
}
[package]
name = "mlua_test"
version = "0.1.0"
authors = ["Alexander Hill <[email protected]>"]
edition = "2018"

[dependencies]
mlua = { version = "0.4.2", features = ["lua54"] }
thread 'main' panicked at 'mlua internal error: Error during disabling C modules (this is a bug, please file an issue): FromLuaConversionError { from: "nil", to: "table", message: None }', /home/ahill/.cargo/registry/src/github.com-1ecc6299db9ec823/mlua-0.4.2/src/lua.rs:169:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

If there's anything I can do to help, let me know. Thanks in advance!

Can't Link Against anything but lua53

Using Vendored & luajit-src

At least that is what I'm assuming is happening. I want to build a module and load it into Love2D. Love2D uses LuaJIT.

I'm building the my_module code from the readme.md (unmodified) and it builds, but then when I load it in either Love2D or LuaJIT it just crashes. (Windows x64, used luapower for luajit).
This is my toml.

[lib]
crate-type = ["cdylib"]

[dependencies]
mlua = { version = "0.3", features = [ "vendored" ] }
mlua_derive = "0.3"
luajit-src = "210"

Without Vendored, Lua 5.1

When I don't put vendored it complains about the header files (which makes sense since I don't have them) but no matter what I do it always complains about lua53 files. I attempt to force it to do lua51 for testing and it gives me this message.

--- stderr
thread 'main' panicked at 'You can enable only one of the features: lua53, lua52, lua51, luajit'

with this toml file

[lib]
crate-type = ["cdylib"]

[dependencies]
mlua = { version = "0.3", features = [ "lua51" ] }
mlua_derive = "0.3"

Thoughts

perhaps I'm missing where to actually define what lua to use? My thoughts is that its building it for lua 5.3 when i used vendored but I want to build it for luajit. This is my first time using rust to talk to anything other than rust so I'm not very experienced with this process.

Thanks

all of this is on Windows 10 x64 with rust 1.41, 2018 edition.

Stacktraces are missing (at least on lua 5.2) for LuaErrors

Description

When a rust function invoked from Lua returns a LuaResult with Error variant, no traceback is available on the lua side. This is especially unfortunate when used with the "module" feature, because within a larger application making use of the module, it may be hard to pinpoint the source of an error without a traceback.

How to reproduce

  1. Compile the reproducer code.
  2. Enter the target/debug directory
  3. Run lua -e 'require "libmlua_error_tb".fun()' (Note: If you don’t have lua52 as default lua, you may need to change the features in the Cargo.toml accordingly)

What happens?

$ lua -e 'require "libmlua_error_tb".fun()'
lua: runtime error: fancy error

What should happen instead?

A proper traceback should be visible, as is the case in the following to other situations:

  • When invoking error from lua directly:

    $ lua -e 'error("foo")'
    lua: (command line):1: foo
    stack traceback:
            [C]: in function 'error'
            (command line):1: in main chunk
            [C]: in ?
    
  • When calling lua_error in a C module with a lua_pushstring error message. This is using a modified version of https://github.com/norman/hello-lua (lua 5.1 though).

    hello.c
    #include "lua.h"
    #include "lauxlib.h"
    
    #define MESSAGE "hello world!"
    
    int say_hello(lua_State *L) {
        lua_pushstring(L, MESSAGE);
        return lua_error(L);
    }
    
    static const struct luaL_Reg functions [] = {
        {"say_hello", say_hello},
        {NULL, NULL}
    };
    
    int luaopen_hello(lua_State *L) {
        luaL_register(L, "hello", functions);
        return 1;
    }
    $ lua5.1 -e 'require"hello"; hello.say_hello(); print("foo")'
    lua5.1: hello world!
    stack traceback:
            [C]: in function 'say_hello'
            (command line):1: in main chunk
            [C]: ?
    

Minimal reproducer

Cargo.toml
[package]
name = "mlua-error-tb"
version = "0.1.0"
authors = ["Jonas Schäfer <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib"]

[dependencies]
mlua = { version = "0.5", features = ["lua52", "module"] }
lib.rs (Variant 1: with LuaError::RuntimeError)
use mlua::prelude::*;

fn lua_fun<'l>(_: &'l Lua, _: ()) -> LuaResult<String> {
	Err(LuaError::RuntimeError(format!("fancy error")))
}

#[mlua::lua_module]
fn libmlua_error_tb(lua: &Lua) -> LuaResult<LuaTable> {
	let exports = lua.create_table()?;

	exports.set("fun", lua.create_function(lua_fun)?)?;

	Ok(exports)
}
lib.rs (Variant 2: with LuaError::ExternalError)
use mlua::prelude::*;
use std::fmt;
use std::sync::Arc;
use std::error::Error;

#[derive(Debug)]
struct FancyError();

impl fmt::Display for FancyError {
	fn fmt<'a>(&self, f: &'a mut fmt::Formatter) -> fmt::Result {
		f.write_str("fancy error")
	}
}

impl Error for FancyError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        None
    }
}

fn lua_fun<'l>(_: &'l Lua, _: ()) -> LuaResult<String> {
	Err(LuaError::ExternalError(Arc::new(FancyError{})))
}

#[mlua::lua_module]
fn libmlua_error_tb(lua: &Lua) -> LuaResult<LuaTable> {
	let exports = lua.create_table()?;

	exports.set("fun", lua.create_function(lua_fun)?)?;

	Ok(exports)
}

Additional thoughts

I looked into the code and I think this is because mlua pushes a userdata instead of a string as error. I guess the sanest way to fix it would be to capture a traceback when returning the error from callback_error in util.rs and attach it to the WrappedError struct. Then implement __tostring in a way which concatenates the traceback with the error message.

To do this, luaL_traceback can probably not be used because it assembles the traceback using the Lua VM, and may probably call longjmp. So a custom implementation based on a loop of lua_getstack and lua_getinfo would be required.

I’m gonna experiment with that because I cannot proceed with my module without this, I have no idea where errors are coming from (I’m making a drop-in replacement for a part of Prosody written in lua, and somewhere I haven’t gotten the API subtleties right yet :)).

Unable to require the module package that I built correctly

os: ubuntu18

rust version:
nightly-x86_64-unknown-linux-gnu (default)
rustc 1.54.0-nightly (f64503eb5 2021-05-23)

  1. cd mlua-master/examples/module

  2. build module
    LUA_INC=/home/yancheng/lua/lua54-bin/include LUA_LIB=/home/yancheng/lua/lua54-bin LUA_LIB_NAME=lua54 cargo build

  3. require the lib

host-1:~/work/rust/mlua-master/target/debug$ ls
build  deps  examples  incremental  libmlua.d  libmlua.rlib  librust_module.d  librust_module.so
host-1:~/work/rust/mlua-master/target/debug$ lua54 -e 'print(require("librust_module").sum(2,3))'
lua54: error loading module 'librust_module' from file './librust_module.so':
        ./librust_module.so: undefined symbol: luaopen_librust_module
stack traceback:
        [C]: in ?
        [C]: in function 'require'
        (command line):1: in main chunk
        [C]: in ?
host-1:~/work/rust/mlua-master/target/debug$

how to resolve it?

FromLuaConversionError

Hi, I might be doing something wrong, but following the doc when I call config.version()in this experiment, I get the following error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: CallbackError { traceback: "stack traceback:\n\tok: in ?\n\tok: in function \'version\'\n\tok:1: in main chunk", cause: FromLuaConversionError { from: "missing argument", to: "userdata", message: None } }', src/app.rs:1461:14
Full stack trace
➜  xplr git:(experiment/lua-integration) RUST_BACKTRACE=full cargo run
warning: unused import: `mlua::prelude::*`
 --> src/app.rs:8:5
  |
8 | use mlua::prelude::*;
  |     ^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: std::io
--> src/app.rs:15:5
|
15 | use std::io;
| ^^^^^^^

warning: 2 warnings emitted

Finished dev [unoptimized + debuginfo] target(s) in 0.03s
 Running `target/debug/xplr`

thread 'main' panicked at 'called Result::unwrap() on an Err value: CallbackError { traceback: "stack traceback:\n\tok: in ?\n\tok: in function 'version'\n\tok:1: in main chunk", cause: FromLuaConversionError { from: "missing argument", to: "userdata", message: None } }', src/app.rs:1461:14
stack backtrace:
0: 0x55a8348f95e0 - std::backtrace_rs::backtrace::libunwind::trace::h25e12e0d899beba0
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
1: 0x55a8348f95e0 - std::backtrace_rs::backtrace::trace_unsynchronized::h70e61195d6ae3df6
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x55a8348f95e0 - std::sys_common::backtrace::_print_fmt::hba93ab80d779695a
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:67:5
3: 0x55a8348f95e0 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hf092b5883b4b2e50
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:46:22
4: 0x55a83491cf1c - core::fmt::write::hf68bc350a8f2f0dc
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/fmt/mod.rs:1078:17
5: 0x55a8348f54e2 - std::io::Write::write_fmt::hf66811b1bc767436
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/io/mod.rs:1517:15
6: 0x55a8348fbc55 - std::sys_common::backtrace::_print::hd425a11bfe1f20f8
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:49:5
7: 0x55a8348fbc55 - std::sys_common::backtrace::print::h6d678795c1e61e13
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:36:9
8: 0x55a8348fbc55 - std::panicking::default_hook::{{closure}}::h78a02a4a0dee5e7e
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:208:50
9: 0x55a8348fb7aa - std::panicking::default_hook::h56eb7eda02f355a7
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:225:9
10: 0x55a8348fc3f1 - std::panicking::rust_panic_with_hook::hb27ea14285131c61
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:591:17
11: 0x55a8348fbf37 - std::panicking::begin_panic_handler::{{closure}}::hc552fcee62aad17f
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:497:13
12: 0x55a8348f9a9c - std::sys_common::backtrace::__rust_end_short_backtrace::hb9f0aa9a78e885a0
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:141:18
13: 0x55a8348fbe99 - rust_begin_unwind
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
14: 0x55a83491b621 - core::panicking::panic_fmt::h12ac4570ea43d06f
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:92:14
15: 0x55a83491b443 - core::option::expect_none_failed::h096fa60f757b7204
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/option.rs:1268:5
16: 0x55a83435f94b - core::result::Result<T,E>::unwrap::h470b858911450ecf
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/result.rs:973:23
17: 0x55a8342e2ba7 - xplr::app::App::create::hef2831627c5aee36
at /home/sayanarijit/Documents/GitHub/xplr/src/app.rs:1457:9
18: 0x55a8342d3bf1 - xplr::main::ha46570f13f262232
at /home/sayanarijit/Documents/GitHub/xplr/src/main.rs:24:15
19: 0x55a8342d284b - core::ops::function::FnOnce::call_once::hb9b31fc0ac524b5a
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/ops/function.rs:227:5
20: 0x55a8342d37fe - std::sys_common::backtrace::__rust_begin_short_backtrace::h5310161e1d1c5292
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/sys_common/backtrace.rs:125:18
21: 0x55a8342d2c21 - std::rt::lang_start::{{closure}}::h5955f30554ec2377
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/rt.rs:66:18
22: 0x55a8348fc907 - core::ops::function::impls::<impl core::ops::function::FnOnce for &F>::call_once::h78040f802d89ccdc
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/ops/function.rs:259:13
23: 0x55a8348fc907 - std::panicking::try::do_call::h6853cad536dd09a1
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:379:40
24: 0x55a8348fc907 - std::panicking::try::h827495f03a9fbb9a
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:343:19
25: 0x55a8348fc907 - std::panic::catch_unwind::h4bdf17571090eb17
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panic.rs:396:14
26: 0x55a8348fc907 - std::rt::lang_start_internal::h2f319c33bb013f29
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/rt.rs:51:25
27: 0x55a8342d2bf7 - std::rt::lang_start::h80802054679dc29e
at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/rt.rs:65:5
28: 0x55a8342d417a - main
29: 0x7fcb76d59b25 - __libc_start_main
30: 0x55a8342d25ee - _start
31: 0x0 -

Usage of Tokio in Modules

Hi there.

Is it possible to use Tokio in modules? Currently, every example I see that uses Tokio is using the standalone mode, and not the module mode. So that's why I asked.

Thanks!

Really strange lifetime error

The following code produces a really strange lifetime error:

extern crate mlua;

use mlua::prelude::{ * };

pub struct MyStruct<'lua> ( &'lua () );

impl<'lua> LuaUserData for MyStruct<'lua> {}

pub fn init<'lua>(lua: &'lua Lua) -> LuaResult<()> {
    lua.globals().set::<_, MyStruct<'lua>>(
        "my_instance",
        MyStruct ( &() ),
    )?;
    Ok(())
}
error[E0477]: the type `MyStruct<'lua>` does not fulfill the required lifetime
  --> err_repo.rs:10:19
   |
10 |     lua.globals().set::<_, MyStruct<'lua>>(
   |                   ^^^
   |
   = note: type must satisfy the static lifetime

I have no clue why its saying that MyStruct isn't a 'static type. Shouldn't an error like this only occur if MyStruct was defined inside of init?

v0.5.1 tag missing

I noticed you have tags and GitHub releases for the other versions, maybe you'd missed this by accident?

`.eval_async()` under `tokio::spawn`

mlua has been amazing in my little hobby project so far, thank you for your work! I come with a question, am running out of ideas.

I'm running mlua under tokio. I'd like to schedule a Lua coroutine from inside a tokio::spawn call (that is, from inside a tokio task), and inspect the results of that Lua coroutine. I've failed to find a way of making this work. The core of the problem seems to be that mlua::Result (or possibly mlua::Lua even?) is !Send, even under the send feature.

I've built a minimal repro: https://gist.github.com/abesto/9dc5ba23e8b46da0f3d5b9db9f46ff53

In context, the relevant part of my real code is at https://github.com/abesto/roo/blob/82106df79736e4acf5d54c4450f1930d7bb10afe/src/server.rs#L79-L81. Any guidance would be appreciated. (I'm currently contemplating creating a new Lua interpreter for the handling of each request, but that feels very wrong)

FTR, the compile error looks like this: https://gist.github.com/abesto/128723dbd85d6e50e7745d9a5de71f24

Can't save LuaFunction

struct Uart<'lua> {
    on_message: LuaFunction<'lua>,
}
impl<'lua> LuaUserData for Uart<'lua> {}


    let exports = lua.create_table()?;
    lua.create_userdata(Uart {
        on_message: lua.create_function(|_, msg: String| Ok(()))?,
    });
    pub fn create_userdata<T>(&self, data: T) -> Result<AnyUserData>
    where
        T: 'static + MaybeSend + UserData,
    {
        unsafe { self.make_userdata(UserDataCell::new(data)) }
    }

I think, create_userdata just need 'lua. Why require 'static?

UserData, FromLua and Clone

Perhaps it's worth changing either the docs for UserData, or require UserData to be implemented only on structs implementing Clone? Otherwise, you can create a struct that implements UserData, but does not implement FromLua, which can lead to headscratching errors, as the docs state that UserData will provide you with an implementation of FromLua.

My usage, boiled down to its most basic form:

struct TestStruct {
    data: Arc<RandomData> //RandomData does not implement clone
}

impl UserData for TestStruct{} //Does not provide a FromLua implementation, because TestStruct does not implement Clone

Add support for `wasm32-unknown-unknown`

At the moment, attempting to build for wasm32-unknown-unknown causes the following panic: don't know how to build Lua for wasm32-unknown-unknown.

I know running Lua in wasm isn't the most efficient thing in the world, but I feel like the functionality should be added.

I'd be happy to look into this, I just want to get the OK before I go and implement it.

Undefined symbol with crate's name uppon loading a module

I was making a module but i couldn't get it to load in Lua.
I made a new test project using the minimal GitHub example.
(crate type : cdylib, module feature and module attribute to main function)
Ive tried vendored and system's variants of Lua5.3.6 and LuaJIT2.1b3.
Gone trough mlua : 0.5.4 and 0.6.0-beta.3.
I also tried using LUA_LINK=static but no luck either.
When require'ing the library, it just reports

error loading module 'liblua_module_test' from file './liblua_module_test.so':
	./liblua_module_test.so: undefined symbol: luaopen_liblua_module_test

I am under Linux (5.12.8-1, Manjaro x64)

Multiple modules in the same build cannot use each others UserData

Description

When having multiple #[mlua::lua_module] entrypoints in the same binary, UserData objects created by one entrypoint are not recognized by the other entrypoint, even though they are the same Rust type.

How to reproduce

  1. Compile the reproducer code.

  2. Run ln -s target/debug/libmlua_multimod.so libmod1.so && ln -s target/debug/libmlua_multimod.so libmod2.so

  3. Run the following lua snippet:

    local m1 = require "libmod1";
    local m2 = require "libmod2";
    local o1 = m1.construct("foo");
    local o2 = m2.construct("bar");
    print(m1.check(o1));
    print(m1.check(o2));
    print(m2.check(o1));
    print(m2.check(o2));

What happens?

The entrypoint for libmod1.so does not recognize the data from libmod2.so and vice-versa, despite both resolving to the very same shared library file and being loaded only once into process memory:

foo
nil     check failed: userdata is not expected type
nil     check failed: userdata is not expected type
bar

What should happen instead?

foo
bar
foo
bar

Minimal reproducer

Cargo.toml
[package]
name = "mlua-multimod"
version = "0.1.0"
authors = ["Jonas Schäfer <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib"]

[dependencies]
mlua = { version = "0.6.0-beta.2", features = ["lua52", "module"] }
src/lib.rs
use mlua::prelude::*;

#[derive(Clone)]
struct CustomData{
	data: String,
}

impl LuaUserData for CustomData {
	fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {

	}
}

fn check<'l>(lua: &'l Lua, v: LuaValue) -> LuaResult<Result<String, String>> {
	match CustomData::from_lua(v, lua) {
		Ok(v) => Ok(Ok(v.data)),
		Err(e) => Ok(Err(format!("check failed: {}", e))),
	}
}

fn construct<'l>(lua: &'l Lua, s: String) -> LuaResult<CustomData> {
	Ok(CustomData{
		data: s,
	})
}

#[mlua::lua_module]
fn libmod1(lua: &Lua) -> LuaResult<LuaTable> {
	let exports = lua.create_table()?;

	exports.set("check", lua.create_function(check)?)?;
	exports.set("construct", lua.create_function(construct)?)?;

	Ok(exports)
}


#[mlua::lua_module]
fn libmod2(lua: &Lua) -> LuaResult<LuaTable> {
	let exports = lua.create_table()?;

	exports.set("check", lua.create_function(check)?)?;
	exports.set("construct", lua.create_function(construct)?)?;

	Ok(exports)
}
test.lua
local m1 = require "libmod1";
local m2 = require "libmod2";
local o1 = m1.construct("foo");
local o2 = m2.construct("bar");
print(m1.check(o1));
print(m1.check(o2));
print(m2.check(o1));
print(m2.check(o2));

Additonal information

The context of this is that I am rewriting parts of a larger lua application in Rust. I want to create drop-in replacements for the various components step-by-step. For that, it is required that one component can work with the data from another component. I currently use different entrypoints for the individual components with the same shared library object.

I can probably work around this by using a single shared library and shim lua wrappers which expose different parts of that shared library under the expected names.

Crash on program exit that has a mlua module loaded

I am currently playing around with mlua as a replacement for a mix of hlua (a fork converted to Lua 5.1) and direct Lua C API calls. Using mlua, especially mlua_derive cleans up my code a lot, and I highly appreciate that mlua works with Lua 5.1 out of the box. Really great work!

I am building Lua modules for game-modding purposes (for DCS World to be more specific). The module is build using mlua_derive. Everything works well, until I exit the game. Once I exit the game, it crashes and the crash is related to my Lua module build with mlua. I am getting the following stack trace:

C:\Windows\SYSTEM32\ntdll.dll
# C0000005 ACCESS_VIOLATION at F2D407D3 00:00000000
0x00000000000407D3 (ntdll): RtlGetCurrentServiceSessionId + 0xBA3
0x000000000003FB91 (ntdll): RtlFreeHeap + 0x51
0x00000000000114CB (ucrtbase): free_base + 0x1B
0x00000000000F6283 (edCore): ed::luaFileCache + 0xD3
0x000000000000D188 (lua): luaM_realloc_ + 0x28
0x000000000000A517 (lua): luaF_newproto + 0x1497
0x000000000001349F (lua): luaM_realloc_ + 0x633F

(the windows event logs also sometimes log a STATUS_HEAP_CORRUPTION instead of the stack trace)

Even though the stacktrace does not mention the DLL I've build, I am prettry sure it is the cause, since it only happens when the DLL is used. Inside the DLL, I could narrow the reason down to lua.create_table(). The crash only happens iff I call lua.create_table() at any point in in the lifetime of the DLL (I even called std::mem::drop(table) on the Rust side to make sure that it's not me having a reference still around; the issue does not happen e.g. when only doing lua.create_string("..")).

I know that this is not a lot of information, and that dealing with such an issue without a reproducible example is quite impossible (I am unable to reproduce it when simply loading the DLL from a Lua repl, and closing the repl). Since I am getting out of ideas, I was still wondering whether this maybe rings any bell for you? As I understand it, the Lua type moves refs into a thread that is added to the registry to prevent the referenced data from getting garbage collected, does this part maybe need to be cleaned up / dropped once the Lua module is unloaded, or is there anything else where mlua potentially retains the ownership of some memory? Any hint is welcome, thanks for your time!

Fail to compile example in the homepage https://crates.io/crates/mlua on windows 10

Cargo.toml:
[dependencies]
mlua = {version = "0.4", features = ["luajit"]}
mlua_derive = "0.4"

Any suggestions? Thanks!

Error information:
error: failed to run custom build command for mlua v0.4.2
Caused by:
process didn't exit successfully: xxx\target\release\build\mlua-3f46c0cec6ba759a\build-script-main (exit code: 101)
--- stdout
cargo:rerun-if-env-changed=LUA_INC
cargo:rerun-if-env-changed=LUA_LIB
cargo:rerun-if-env-changed=LUA_LIB_NAME
cargo:rerun-if-env-changed=LUA_LINK
cargo:rerun-if-env-changed=LUAJIT_NO_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG
cargo:rerun-if-env-changed=LUAJIT_STATIC
cargo:rerun-if-env-changed=LUAJIT_DYNAMIC
cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-pc-windows-msvc
cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_pc_windows_msvc
cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH
cargo:rerun-if-env-changed=PKG_CONFIG_PATH
cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-pc-windows-msvc
cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_pc_windows_msvc
cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR
cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-pc-windows-msvc
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_pc_windows_msvc
cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR

--- stderr
thread 'main' panicked at 'called Result::unwrap() on an Err value: Command { command: ""pkg-config" "--libs" "--cflags" "luajit" "luajit >= 2.0.5"", cause: Os { code: 2, kind: NotFound, message: "系统找不到指定的文件(System cant't find the file)" } }', d:\Tools\rust\.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-ed15b681fafda09b\mlua-0.4.2\build\find_normal.rs:100:13
stack backtrace:
0: 0x7ff795a97d29 - std::backtrace_rs::backtrace::dbghelp::trace
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src....\backtrace\src\backtrace\dbghelp.rs:98
1: 0x7ff795a97d29 - std::backtrace_rs::backtrace::trace_unsynchronized
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src....\backtrace\src\backtrace\mod.rs:66
2: 0x7ff795a97d29 - std::sys_common::backtrace::_print_fmt
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\sys_common\backtrace.rs:79
3: 0x7ff795a97d29 - std::sys_common::backtrace::_print::{{impl}}::fmt
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\sys_common\backtrace.rs:58
4: 0x7ff795aaedbb - core::fmt::write
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\core\src\fmt\mod.rs:1082
5: 0x7ff795a92ee4 - std::io::Write::write_fmtstd::sys::windows::stdio::Stderr
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\io\mod.rs:1514
6: 0x7ff795a9b29b - std::sys_common::backtrace::_print
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\sys_common\backtrace.rs:61
7: 0x7ff795a9b29b - std::sys_common::backtrace::print
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\sys_common\backtrace.rs:48
8: 0x7ff795a9b29b - std::panicking::default_hook::{{closure}}
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panicking.rs:200
9: 0x7ff795a9aed9 - std::panicking::default_hook
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panicking.rs:219
10: 0x7ff795a9ba7f - std::panicking::rust_panic_with_hook
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panicking.rs:569
11: 0x7ff795a9b5e5 - std::panicking::begin_panic_handler::{{closure}}
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panicking.rs:476
12: 0x7ff795a985df - std::sys_common::backtrace::__rust_end_short_backtrace<closure-0,!>
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\sys_common\backtrace.rs:153
13: 0x7ff795a9b599 - std::panicking::begin_panic_handler
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panicking.rs:475
14: 0x7ff795aae060 - core::panicking::panic_fmt
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\core\src\panicking.rs:85
15: 0x7ff795aade83 - core::option::expect_none_failed
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\core\src\option.rs:1221
16: 0x7ff7959f5880 - core::result::Result<T,E>::unwrap::h4abe766c37c2e663
17: 0x7ff7959f13f5 - build_script_main::find::probe_lua::hbc91469b81609887
18: 0x7ff7959f4ff2 - <std::process::Command as build_script_main::CommandExt>::execute::{{closure}}::h5c4ffc21a23723af
19: 0x7ff7959f36c6 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h43612d4e10ce1abd
20: 0x7ff7959f3607 - std::sys_common::backtrace::__rust_begin_short_backtrace::he397c93ac43ec166
21: 0x7ff7959f5c2c - std::rt::lang_start::{{closure}}::h56c7c24389f962f2
22: 0x7ff795a9bc86 - core::ops::function::impls::{{impl}}::call_once
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39\library\core\src\ops\function.rs:280
23: 0x7ff795a9bc86 - std::panicking::try::do_call
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panicking.rs:373
24: 0x7ff795a9bc86 - std::panicking::try
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panicking.rs:337
25: 0x7ff795a9bc86 - std::panic::catch_unwind
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\panic.rs:379
26: 0x7ff795a9bc86 - std::rt::lang_start_internal
at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library\std\src\rt.rs:51
27: 0x7ff7959f5c04 - std::rt::lang_start::h7b1072503172a0d1
28: 0x7ff7959f5050 - main
29: 0x7ff795ab3b60 - invoke_main
at d:\agent_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
30: 0x7ff795ab3b60 - __scrt_common_main_seh
at d:\agent_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
31: 0x7ffa5b637034 - BaseThreadInitThunk
32: 0x7ffa5cbfcec1 - RtlUserThreadStart

[Question] Storing a Lua value of unknown type into a variable?

(This is a support request more than an "issue". If there is a better place to ask mlua questions I'd be happy to go there. I am new to both mlua and Rust. Thanks.)

So I am looking over the docs and example code and I see I can pull a value out of a Lua table or out of globals by calling get() and typing it:

let package:LuaTable = globals.get("package")?;

But I can't do this without typing the variable. If I just say:

let package = globals.get("package")?;

…that is a compile error. I haven't tested but I assume (?) the type is checked when I get() and if I say something incorrect, like let package:String = globals.get("package")?; where package turns out to be a table at runtime, this will be a runtime error.

Let's say I want to store a Lua value in a variable without caring what the type is. Like say I want to say

let abcd = globals.get("abcd")?;
globals.set("efgh", abcd)?;

In this case I do not actually "look inside" the abcd value, I just want to copy it from one Lua name to another. Is there a type I can use in that case?

(I think any will work, but my understanding— I am new to this— is that any is literally any type, including Rust types, but I am wanting to stay within the bounds of types that mlua can bind to Lua values.)

Error when compiling a module for luajit or lua51 or lua52

Hello,

I can build the example module for lua53:

git clone https://github.com/khvzak/mlua.git
cd mlua/examples/module
sed -i '/^mlua/s/\[.*\]/["luajit", "module"]/' Cargo.toml   ## feature lua53
cargo build

But if I do the same for luajit (or lua51 or lua52):

sed -i '/^mlua/s/\[.*\]/["luajit", "module"]/' Cargo.toml   ## feature luajit
cargo build

I get these errors:

error[E0599]: no associated item named `EPSILON` found for type `f64` in the current scope
   --> src/ffi/compat53.rs:292:54
    |
292 |         if (n - i as lua_Number).abs() < lua_Number::EPSILON {
    |                                                      ^^^^^^^ associated item not found in `f64`

error[E0599]: no associated item named `EPSILON` found for type `f64` in the current scope
   --> src/ffi/compat53.rs:318:65
    |
318 |     if ok != 0 && (n - n_int as lua_Number).abs() < lua_Number::EPSILON {
    |                                                                 ^^^^^^^ associated item not found in `f64`

This is with rustc 1.41.0.

Is it a bug ?

is there a way to create rust-owned data and modify it with userdata from lua side?

Is it possible to create rust-owned state on rust side which is not passed to lua; and change this state from the userdata methods defined and passed to lua?

My goal is to create tables on lua side and somehow register these tables in the order that they are created. And the order is very important.

So for example on lua side I will have this:

function main(v)
  v:addRow({ _type.= "row", pos: 1 })
end
#[derive(Debug, Clone)]
struct V {
  n: u32,
  extern_val: Option<String>,
}

impl UserData for V {
  fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
    methods.add_method_mut("foo", |_, it, val: String| {
      println!("setting {} to self.extern_val", val);
      it.extern_val = Some(val);
     // somehow get a state and save val to it?
      Ok(())
    });
  }
}

v is an instance of the userdata. And so the next step would be to somehow get whatever was passed into the addRow method of that userdata and save it somewhere in the rust side.

Can I somehow do that?

Thanks in advance

[Feature Request] Loading external libraries

I've been using mlua to provide scripting for my application, and it's doing a fantastic job. However, I would like users to have access to a few other external libraries, such as lbc and LuaSQLite3. At present, the only way to do that seems to be initializing the state myself, calling the various initialization functions on it, and then passing that state to Lua::init_from_ptr. However, that seems like not a particularly good approach for several reasons:

  • I can't set .ephemeral = false
  • I'm using LuaJIT, so I don't have access to luaL_requiref (I would use your Rust port of compat-5.3 if it were a standalone package!)
  • Loading the standard libraries is kind of a drag, and it seems like they should be loaded after init_from_ptr

If there were some kind of unsafe fn new_with_libraries that accepts arguments for luaL_requiref, that would solve the problem. I suppose a more brute-force approach would be to simply accept a closure of FnOnce(&mut lua_State) during initialization. I of course understand that loading arbitrary external libraries would break all safety guarantees, but I think it would still be preferable to using init_from_ptr, which as far as I can tell is my only option right now.

`__gc` metamethod might be useful

Hi!

I created a userdata just a handler with a field index, which the real value store in Lua.

I want to delete the real value when the userdata is gced. But I can't find a way to do it just with imple the Drop trait.

Any idea?

maybe add PartialEq to Error

Hi! Currently I am wrapping mlua Error with basically the same fields + PartialEq to be able to write tests for my program. Can you add PartialEq to the Error?

Or if you don't have time maybe I can do it?

Many thanks in advance, loving where your project got from rlua, many changes I think are definitely for the better!

Cross-compilation error.

Hello, I am trying to cross-compile mlua using the target-triple i686-pc-windows-gnu, however, I am receiving the following error:

error: failed to run custom build command for `mlua v0.4.2`

Caused by:
  process didn't exit successfully: `C:\Users\amitv\Desktop\santal\target\debug\build\mlua-77dffc5237f357f7\build-script-main` (exit code: 101)
  --- stdout
  cargo:rerun-if-env-changed=LUA_INC
  cargo:rerun-if-env-changed=LUA_LIB
  cargo:rerun-if-env-changed=LUA_LIB_NAME
  cargo:rerun-if-env-changed=LUA_LINK
  cargo:rerun-if-env-changed=LUA_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_i686-pc-windows-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_i686_pc_windows_gnu
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_i686-pc-windows-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_i686_pc_windows_gnu
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_i686-pc-windows-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_i686_pc_windows_gnu
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=LUA5.4_NO_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_i686-pc-windows-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_i686_pc_windows_gnu
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
  cargo:rerun-if-env-changed=PKG_CONFIG_i686-pc-windows-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_i686_pc_windows_gnu
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_i686-pc-windows-gnu
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_i686_pc_windows_gnu
  cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
  cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR

  --- stderr
  thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: CrossCompilation', C:\Users\amitv\.cargo\registry\src\github.com-1ecc6299db9ec823\mlua-0.4.2\build\find_normal.rs:42:13
  stack backtrace:
     0: std::panicking::begin_panic_handler
               at /rustc/ffa2e7ae8fbf9badc035740db949b9dae271c29f\/library\std\src\panicking.rs:483
     1: core::panicking::panic_fmt
               at /rustc/ffa2e7ae8fbf9badc035740db949b9dae271c29f\/library\core\src\panicking.rs:85
     2: core::option::expect_none_failed
               at /rustc/ffa2e7ae8fbf9badc035740db949b9dae271c29f\/library\core\src\option.rs:1268
     3: core::result::Result<pkg_config::Library, pkg_config::Error>::unwrap<pkg_config::Library,pkg_config::Error>
               at C:\Users\amitv\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\result.rs:973
     4: build_script_main::find::probe_lua
               at .\build\find_normal.rs:42
     5: build_script_main::main
               at .\build\main.rs:134
     6: core::ops::function::FnOnce::call_once<fn(),tuple<>>
               at C:\Users\amitv\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227

Any help would be very appreciated.

Regards,
Amit.

Any reason why the event field of lua_Debug is not exposed through the Debug struct?

I noticed that with the interface that mlua provides, I cannot tell why the hook was called.

Skimming through mlua and lua source code it seems like the event property of lua_Debug struct has an event field which might be what I'm looking for.

https://github.com/khvzak/mlua/blob/1d7f105585e4f961967ee8d8cbd8fbfbc4787281/src/ffi/lua.rs#L792

So my question is, is there any reason why that field is not exposed through the rust wrapper Debug ?

Add Coco support (5.1 and JIT)

See https://coco.luajit.org/index.html:

Coco — True C Coroutines for Lua

Coco is a small extension to get True C Coroutine semantics for Lua 5.1. Coco is available as a patch set against the standard Lua 5.1.5 source distribution.

Features

True C coroutine semantics mean you can yield from a coroutine across a C call boundary and resume back to it. Coco allows you to use a dedicated C stack for each coroutine. Resuming a coroutine and yielding from a coroutine automatically switches C stacks. No changes are needed to your Lua source code.

In particular you can now:

  • Yield across all metamethods (not advised for __gc).
  • Yield across iterator functions (for x in func do).
  • Yield across callbacks (table.foreach(), dofile(), ...).
  • Yield across protected callbacks (pcall(), xpcall(), ...).
  • Yield from C functions and resume back to them.

It would be really cool to see support for this in mlua, especially since some things are simply unfeasible with other patch sets (see MCJack123/craftos2#184 for an example). It is very cool that every function call suddenly, magically, starts to support yielding, without you having to add special cases and set contexts and use gotos. I have worked with resumable C functions before and it is quite the mind bender. I also think that its semantics are compatible with Safe Rust, more so than the ReusableVmPatch.

[Question] Mass-registration of functions / equivalent of luaL_register?

(This is a support request more than an "issue". If there is a better place to ask mlua questions I'd be happy to go there. I am new to both mlua and Rust. Thanks.)

In the Lua C library there is a function luaL_register that allows you to load many functions into a table at once, usually package.preload. This is useful for loading an entire C API into Lua all at once. Example:

Screen Shot 2021-02-20 at 2 58 32 PM

What would be the closest mlua equivalent to this? I am looking over the docs and don't see anything specific.

My intuition is "oh, I will just make an array, and iterate over the array calling create_function". But then I run into interesting difficulties with the fact I cannot really store a heterogenous array of functions with different signatures into a single variable to iterate over, and it also seems I cannot easily create an array of mlua:;Function objects (at least, not in its own module) because of Rust rules about storing unsafe/thread-global mutable data into a static.

I'm sure I will figure something out, but I wonder, is there a "best practices" mlua pattern for this?

How to convert Vec<u8> to Lua string?

I don't know if this is possible and nothing I've tried works, so I'm asking here.
I'm working on a module that loads binary data as Vec<u8>, and I need this data to be available in Lua as a string. (I am working with Love2D which uses binary image data as strings.) I cannot convert it to a Rust String because it would not be valid UTF-8. The closest I can get is data.to_lua(&lua) (where data is Vec<u8>), but this gives a table.
Is there a way to do this?

The way to return self for chain call

I want a way to use userdata like

local a = BuilderUD()

local res = a:with(1):with(2):build()

But when I return Ok(*this), I will get the error

move occurs because `*this` has type `xxxxxxx`, which does not implement the `Copy` trait

I suspect there is a better way to do with this condition.

Building for target armv7-unknown-linux-gnueabihf error

It seems that the mlua could not build for target armv7-unknown-linux-gnueabihf. When I executed:

cargo build --target armv7-unknown-linux-gnueabihf

I got these error message:

 running: "arm-linux-gnueabihf-ar" "crs" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/liblua5.3.a" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lapi.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lauxlib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lbaselib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lcode.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/ldblib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/ldebug.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/ldo.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/ldump.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lfunc.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lgc.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/linit.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/liolib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/llex.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lmathlib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lmem.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/loadlib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lobject.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lopcodes.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/loslib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lparser.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lstate.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lstring.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lstrlib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/ltable.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/ltablib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/ltm.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lundump.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lvm.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lzio.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lbitlib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lcorolib.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lctype.o" "/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib/lutf8lib.o"
  exit code: 0
  cargo:rustc-link-search=native=/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib
  cargo:rustc-link-lib=static=lua5.3
  cargo:include=/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/include
  cargo:lib=/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/lua-build/lib
  OPT_LEVEL = Some("0")
  TARGET = Some("armv7-unknown-linux-gnueabihf")
  HOST = Some("x86_64-unknown-linux-gnu")
  CC_armv7-unknown-linux-gnueabihf = None
  CC_armv7_unknown_linux_gnueabihf = None
  TARGET_CC = None
  CC = None
  CROSS_COMPILE = None
  CFLAGS_armv7-unknown-linux-gnueabihf = None
  CFLAGS_armv7_unknown_linux_gnueabihf = None
  TARGET_CFLAGS = None
  CFLAGS = None
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")
  CARGO_CFG_TARGET_FEATURE = None

  --- stderr
  thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "The command \"/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/glue\" \"/home/zhen/works/rust/t01/target/armv7-unknown-linux-gnueabihf/debug/build/mlua-1e626287640eeec6/out/glue.rs\" did not run successfully." }', mlua/build/main.rs:91:10
  stack backtrace:
     0: backtrace::backtrace::libunwind::trace
               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
     1: backtrace::backtrace::trace_unsynchronized
               at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
     2: std::sys_common::backtrace::_print_fmt
               at src/libstd/sys_common/backtrace.rs:78
     3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
               at src/libstd/sys_common/backtrace.rs:59
     4: core::fmt::write
               at src/libcore/fmt/mod.rs:1076
     5: std::io::Write::write_fmt
               at src/libstd/io/mod.rs:1537
     6: std::sys_common::backtrace::_print
               at src/libstd/sys_common/backtrace.rs:62
     7: std::sys_common::backtrace::print
               at src/libstd/sys_common/backtrace.rs:49
     8: std::panicking::default_hook::{{closure}}
               at src/libstd/panicking.rs:198
     9: std::panicking::default_hook
               at src/libstd/panicking.rs:217
    10: std::panicking::rust_panic_with_hook
               at src/libstd/panicking.rs:526
    11: rust_begin_unwind
               at src/libstd/panicking.rs:437
    12: core::panicking::panic_fmt
               at src/libcore/panicking.rs:85
    13: core::option::expect_none_failed
               at src/libcore/option.rs:1269
    14: core::result::Result<T,E>::unwrap
               at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libcore/result.rs:1005
    15: build_script_main::build_glue
               at mlua/build/main.rs:88
    16: build_script_main::main
               at mlua/build/main.rs:135
    17: std::rt::lang_start::{{closure}}
               at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/rt.rs:67
    18: std::rt::lang_start_internal::{{closure}}
               at src/libstd/rt.rs:52
    19: std::panicking::try::do_call
               at src/libstd/panicking.rs:348
    20: std::panicking::try
               at src/libstd/panicking.rs:325
    21: std::panic::catch_unwind
               at src/libstd/panic.rs:394
    22: std::rt::lang_start_internal
               at src/libstd/rt.rs:51
    23: std::rt::lang_start
               at /rustc/04488afe34512aa4c33566eb16d8c912a3ae04f9/src/libstd/rt.rs:67
    24: main
    25: __libc_start_main
    26: _start
  note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

serde

I know that there‘s mlua_serde but is there any plan to add serde support to mlua directly? Maybe behind a serde feature flag?

The main reason is that it would allow a better integration: mlua_serde currently skips a few Value variants like Value::UserData. Deserializing user data would be a nice feature, especially when it contains some strict types. But in order to do this, I think we’d need the T: UserData + Serialize + Deserialize bound for AnyUserData internally.

Undefined symbol error when importing module into Lua 5.1

Lua 5.1 is unable to import a module built with mlua even though cargo builds it without error.

Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require("librust_module")
error loading module 'librust_module' from file './librust_module.so':
	./librust_module.so: undefined symbol: luaopen_librust_module
stack traceback:
	[C]: ?
	[C]: in function 'require'
	stdin:1: in main chunk
	[C]: ?

My Cargo.toml (taken and modified from the example in the repo):

[package]
name = "rust_module"
version = "0.0.0"
authors = ["Aleksandr Orlenko <[email protected]>"]
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
lua-src = "542.0.0"
mlua = { version = "0.4.2", features = ["lua51", "vendored", "module"] }
mlua_derive = "0.4.0"

My lib.rs:

use mlua::prelude::*;

fn sum(_: &Lua, (a, b): (i64, i64)) -> LuaResult<i64> {
    Ok(a + b)
}

fn used_memory(lua: &Lua, _: ()) -> LuaResult<usize> {
    Ok(lua.used_memory())
}

#[mlua_derive::lua_module]
fn rust_module(lua: &Lua) -> LuaResult<LuaTable> {
    let exports = lua.create_table()?;
    exports.set("sum", lua.create_function(sum)?)?;
    exports.set("used_memory", lua.create_function(used_memory)?)?;
    Ok(exports)
}

I'm building on Pop! OS Linux 20.04. Rust version: rustc 1.49.0 (e1884a8e3 2020-12-29)
Built with: cargo build --release
I am a novice programmer so if you could please ELI5 I would greatly appreciate it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.