c_void causes internal error
Creating a userdata method with a LightUserData as an argument, then passing a void pointer to that method, causes the following error:
thread '<unnamed>' panicked at 'mlua internal error: LUA_TNONE in pop_value (this is a bug, please file an issue)', /home/username/.cargo/registry/src/github.com-1ecc6299db9ec823/mlua-0.7.3/src/lua.rs:1991:18
minimal reproduction: main.lua:
ffi = require 'ffi'
pwd = io.popen('pwd'):read('*l')
print(pwd)
test = assert(package.loadlib(pwd .. '/target/debug/libminimal_tnone.so', 'luaopen_test'))()
test:buggy(ffi.cast('void *', ffi.new('int[1]')))
lib.rs:
use mlua::prelude::*;
struct Test;
#[mlua::lua_module]
fn test(lua: &Lua) -> LuaResult<Test> {
Ok(Test)
}
impl mlua::UserData for Test {
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_method("buggy", |_, _, ptr: mlua::LightUserData| Ok("kaboom") );
}
}
Cargo.toml:
[package]
name = "minimal_tnone"
version = "0.1.0"
edition = "2021"
[dependencies]
mlua = {version = "0.7.3", features = ["luajit", "vendored", "module"]}
[lib]
crate-type = ["cdylib"]
This is on linux, x86. It's kinda annoying because a void * is a very useful thing to be able to pass from lua to rust.
aptarshi Guha wrote:
> I hope i haven't missed this, but does the C function lua_type return 10
> for cdata objects? Is there #define for this (e.g. like LUA_TCDATA)
Only internally. But, yes, it's guaranteed to be 10 for LuaJIT 2.0.
> Or is there another better way to check whether a lua object is a CDATA.
No, because the classic Lua/C API and the FFI shouldn't be mixed.
Deal with cdata on the Lua side only. Call C functions that need
to be passed cdata only via the FFI.
--Mike
https://www.freelists.org/post/luajit/Type-of-CDATA-as-returned-by-lua-type,1
And it's the same problem (int lua_type() returns 10).
So I guess this is all my bad (or perhaps the error message should be updated to inform the user that mixing luajit's ffi capabilities and mlua is not supported?)
Yeah, LUA_TCDATA is an internal LuaJIT type not supported by mlua (as well as LUA_TPROTO).
I'll update the error message, thanks!
Maybe you can do a trick and pass a pointer as a number: tonumber(ffi.cast('uint64_t', ffi.new('int[1]'))) but it's highly unsafe.