mlua icon indicating copy to clipboard operation
mlua copied to clipboard

c_void causes internal error

Open nowakf opened this issue 4 years ago • 2 comments

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.

nowakf avatar Feb 10 '22 13:02 nowakf

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?)

nowakf avatar Feb 10 '22 14:02 nowakf

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.

khvzak avatar Feb 10 '22 23:02 khvzak