Skip to content

Instantly share code, notes, and snippets.

@MikuAuahDark
Created October 3, 2017 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MikuAuahDark/913287479f8b165b1986bf68383cfdb2 to your computer and use it in GitHub Desktop.
Save MikuAuahDark/913287479f8b165b1986bf68383cfdb2 to your computer and use it in GitHub Desktop.
Lua 5.2 FFI Binding for Lua FFI library
-- A very basic Lua 5.2 FFI binding.
-- Tested under LuaJIT FFI, but should work under Facebook LuaFFI too
-- This assume:
-- - lua_Number is double
-- - lua_Integer is ptrdiff_t (equal to size_t?)
-- - lua_Unsigned is unsigned int
-- Released under public domain
local ffi = require("ffi")
local lua52 = ffi.load("lua52")
local null = ffi.cast("void*", 0)
ffi.cdef [[
typedef struct lua_State lua_State;
typedef int (*lua_CFunction) (lua_State *L);
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
typedef double lua_Number;
typedef ptrdiff_t lua_Integer;
typedef unsigned int lua_Unsigned;
lua_State *(lua_newstate) (lua_Alloc f, void *ud);
void (lua_close) (lua_State *L);
lua_State *(lua_newthread) (lua_State *L);
lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
const lua_Number *(lua_version) (lua_State *L);
int (lua_absindex) (lua_State *L, int idx);
int (lua_gettop) (lua_State *L);
void (lua_settop) (lua_State *L, int idx);
void (lua_pushvalue) (lua_State *L, int idx);
void (lua_remove) (lua_State *L, int idx);
void (lua_insert) (lua_State *L, int idx);
void (lua_replace) (lua_State *L, int idx);
void (lua_copy) (lua_State *L, int fromidx, int toidx);
int (lua_checkstack) (lua_State *L, int sz);
void (lua_xmove) (lua_State *from, lua_State *to, int n);
int (lua_isnumber) (lua_State *L, int idx);
int (lua_isstring) (lua_State *L, int idx);
int (lua_iscfunction) (lua_State *L, int idx);
int (lua_isuserdata) (lua_State *L, int idx);
int (lua_type) (lua_State *L, int idx);
const char *(lua_typename) (lua_State *L, int tp);
lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
int (lua_toboolean) (lua_State *L, int idx);
const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
size_t (lua_rawlen) (lua_State *L, int idx);
lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
void *(lua_touserdata) (lua_State *L, int idx);
lua_State *(lua_tothread) (lua_State *L, int idx);
const void *(lua_topointer) (lua_State *L, int idx);
void (lua_arith) (lua_State *L, int op);
int (lua_rawequal) (lua_State *L, int idx1, int idx2);
int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
void (lua_pushnil) (lua_State *L);
void (lua_pushnumber) (lua_State *L, lua_Number n);
void (lua_pushinteger) (lua_State *L, lua_Integer n);
void (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l);
const char *(lua_pushstring) (lua_State *L, const char *s);
const char *(lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp);
const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
void (lua_pushboolean) (lua_State *L, int b);
void (lua_pushlightuserdata) (lua_State *L, void *p);
int (lua_pushthread) (lua_State *L);
void (lua_getglobal) (lua_State *L, const char *var);
void (lua_gettable) (lua_State *L, int idx);
void (lua_getfield) (lua_State *L, int idx, const char *k);
void (lua_rawget) (lua_State *L, int idx);
void (lua_rawgeti) (lua_State *L, int idx, int n);
void (lua_rawgetp) (lua_State *L, int idx, const void *p);
void (lua_createtable) (lua_State *L, int narr, int nrec);
void *(lua_newuserdata) (lua_State *L, size_t sz);
int (lua_getmetatable) (lua_State *L, int objindex);
void (lua_getuservalue) (lua_State *L, int idx);
void (lua_setglobal) (lua_State *L, const char *var);
void (lua_settable) (lua_State *L, int idx);
void (lua_setfield) (lua_State *L, int idx, const char *k);
void (lua_rawset) (lua_State *L, int idx);
void (lua_rawseti) (lua_State *L, int idx, int n);
void (lua_rawsetp) (lua_State *L, int idx, const void *p);
int (lua_setmetatable) (lua_State *L, int objindex);
void (lua_setuservalue) (lua_State *L, int idx);
void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k);
int (lua_getctx) (lua_State *L, int *ctx);
int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k);
int (lua_load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode);
int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
int (lua_yieldk) (lua_State *L, int nresults, int ctx, lua_CFunction k);
int (lua_resume) (lua_State *L, lua_State *from, int narg);
int (lua_status) (lua_State *L);
int (lua_gc) (lua_State *L, int what, int data);
int (lua_error) (lua_State *L);
int (lua_next) (lua_State *L, int idx);
void (lua_concat) (lua_State *L, int n);
void (lua_len) (lua_State *L, int idx);
lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
typedef struct lua_Debug lua_Debug;
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
void *(lua_upvalueid) (lua_State *L, int fidx, int n);
void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, int fidx2, int n2);
int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
lua_Hook (lua_gethook) (lua_State *L);
int (lua_gethookmask) (lua_State *L);
int (lua_gethookcount) (lua_State *L);
struct lua_Debug {
int event;
const char *name;
const char *namewhat;
const char *what;
const char *source;
int currentline;
int linedefined;
int lastlinedefined;
unsigned char nups;
unsigned char nparams;
char isvararg;
char istailcall;
char short_src[60];
struct CallInfo *i_ci;
};
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
void (luaL_checkversion_) (lua_State *L, lua_Number ver);
int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
int (luaL_callmeta) (lua_State *L, int obj, const char *e);
const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
const char *(luaL_checklstring) (lua_State *L, int numArg, size_t *l);
const char *(luaL_optlstring) (lua_State *L, int numArg, const char *def, size_t *l);
lua_Number (luaL_checknumber) (lua_State *L, int numArg);
lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
lua_Integer (luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, lua_Unsigned def);
void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
void (luaL_checktype) (lua_State *L, int narg, int t);
void (luaL_checkany) (lua_State *L, int narg);
int (luaL_newmetatable) (lua_State *L, const char *tname);
void (luaL_setmetatable) (lua_State *L, const char *tname);
void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
void (luaL_where) (lua_State *L, int lvl);
int (luaL_error) (lua_State *L, const char *fmt, ...);
int (luaL_checkoption) (lua_State *L, int narg, const char *def, const char *const lst[]);
int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
int (luaL_execresult) (lua_State *L, int stat);
int (luaL_ref) (lua_State *L, int t);
void (luaL_unref) (lua_State *L, int t, int ref);
int (luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
int (luaL_loadstring) (lua_State *L, const char *s);
lua_State *(luaL_newstate) (void);
int (luaL_len) (lua_State *L, int idx);
const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r);
void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
void (luaL_traceback) (lua_State *L, lua_State *L1, const char *msg, int level);
void (luaL_requiref) (lua_State *L, const char *modname, lua_CFunction openf, int glb);
typedef struct luaL_Buffer {
char *b;
size_t size;
size_t n;
lua_State *L;
char initb[512];
} luaL_Buffer;
void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
void (luaL_addstring) (luaL_Buffer *B, const char *s);
void (luaL_addvalue) (luaL_Buffer *B);
void (luaL_pushresult) (luaL_Buffer *B);
void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
typedef struct FILE FILE;
typedef struct luaL_Stream {
FILE *f;
lua_CFunction closef;
} luaL_Stream;
int (luaopen_base) (lua_State *L);
int (luaopen_coroutine) (lua_State *L);
int (luaopen_table) (lua_State *L);
int (luaopen_io) (lua_State *L);
int (luaopen_os) (lua_State *L);
int (luaopen_string) (lua_State *L);
int (luaopen_bit32) (lua_State *L);
int (luaopen_math) (lua_State *L);
int (luaopen_debug) (lua_State *L);
int (luaopen_package) (lua_State *L);
void (luaL_openlibs) (lua_State *L);
]]
local function indexing_ffi(mod, name)
return mod[name]
end
local function safe_indexing_ffi(mod, name)
local s, m = pcall(indexing_ffi, mod, name)
if s then
return m
end
return nil
end
local lua52m = setmetatable({}, {
__index = function(self, var)
if var:find("aux_", 1, true) then
local auxn = "luaL_"..var:sub(5)
return rawget(self, auxn) or safe_indexing_ffi(lua52, auxn)
else
local auxn = "lua_"..var
return rawget(self, auxn) or rawget(self, var) or
safe_indexing_ffi(lua52, auxn) or safe_indexing_ffi(lua52, var)
end
end
})
function lua52m.lua_call(L, n, r)
return lua52.lua_callk(L, n, r, 0, nil)
end
function lua52m.lua_pcall(L, n, r, f)
return lua52.lua_pcall(L, n, r, f, 0, nil)
end
function lua52m.lua_yield(L, n)
return lua52.lua_yieldk(L, n, 0, nil)
end
function lua52m.lua_tonumber(L, i)
return lua52.lua_tonumberx(L, i, nil)
end
function lua52m.lua_tointeger(L, i)
return lua52.lua_tointegerx(L, i, nil)
end
function lua52m.lua_tounsigned(L, i)
return lua52.lua_tounsigned(L, i, nil)
end
function lua52m.lua_pop(L, n)
return lua52.lua_settop(L, -(n)-1)
end
function lua52m.lua_newtable(L)
return lua52.lua_createtable(L, 0, 0)
end
function lua52m.pushcfunction(L, f)
return lua52.lua_pushcclosure(L, f, 0)
end
function lua52m.luaL_newstate()
local L = lua52.luaL_newstate()
if L == null then
return nil, "Not enough memory"
end
return ffi.gc(L, lua52.lua_close)
end
ffi.metatype("lua_State", {
__index = lua52m
})
return lua52m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment