Created
October 3, 2017 13:20
-
-
Save MikuAuahDark/913287479f8b165b1986bf68383cfdb2 to your computer and use it in GitHub Desktop.
Lua 5.2 FFI Binding for Lua FFI library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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