I have an existing application that uses the standard Lua API to wrap some simple C++ classes as full userdata objects. Converting entirely to an FFI-based interface would be significant work so I'd like instead to improve the performance of a few critical methods & metamethods by replacing them with FFI functions, having the userdata as the first (void*) argument. It seems that this works for a simple method but not for a metamethod. The following example demonstrates the problem using a userdata that simply holds a number: /* test.cpp */ #include "lua.hpp" extern "C" { // returns a userdata with an empty metatable int luaopen_testmodule(lua_State * L) { void * ud = lua_newuserdata(L,8); * reinterpret_cast<double*>(ud) = 123.456; lua_newtable(L); lua_setmetatable(L,-2); return 1; } double get_double(void * ud) { return * reinterpret_cast<double*>(ud); } } ------ test.lua local ffi = require'ffi' ffi.cdef[[ double get_double(void *); ]] clib = ffi.load'test' ud = require'testmodule' getmetatable(ud).__index = { get = clib.get_double } print(ud:get()) -- ok getmetatable(ud).__call = clib.get_double print(ud()) -- Error ------ outputs: 123.456 ...test.lua:16: attempt to call global 'ud' (a userdata value) (Tested using latest git version on Linux x64 & v2.0.0-beta10 on Windows x64) The simple FFI method call to ud:get() works as expected, but the metamethod __call fails. I encountered similar behaviour with other metamethods, but with different errors. I understand that changing metamethods on cdata objects is disallowed, but that is not the case here. Is there a way to get this to work for metamethods, or is this behaviour not supported? Thanks, Simon