#include "commons/commons_luajit.h" #include "commons/commons_base.h" typedef struct lua_State lua_State; typedef int (*lua_CFunction)(lua_State*); typedef long long lua_Integer; #define LUA_MULTRET (-1) #define LUA_TNUMBER 3 #define LUA_TSTRING 4 #define LUA_GLOBALSINDEX (-10002) #define LUAJIT_SYMBOLS(X) \ X(luaL_newstate, lua_State*, (void)) \ X(luaL_openlibs, void, (lua_State*)) \ X(lua_close, void, (lua_State*)) \ X(luaL_loadfile, int, (lua_State*, const char*)) \ X(lua_pcall, int, (lua_State*, int, int, int)) \ X(lua_tolstring, const char*, (lua_State*, int, size_t*)) \ X(lua_tonumber, double, (lua_State*, int)) \ X(lua_tointeger, lua_Integer, (lua_State*, int)) \ X(lua_pushnumber, void, (lua_State*, double)) \ X(lua_pushstring, void, (lua_State*, const char*)) \ X(lua_pushcclosure, void, (lua_State*, lua_CFunction, int)) \ X(lua_setfield, void, (lua_State*, int, const char*)) \ X(lua_createtable, void, (lua_State*, int, int)) \ X(lua_gettop, int, (lua_State*)) \ X(lua_type, int, (lua_State*, int)) #define DECLARE_LUAJIT_SYMBOL(name, ret, args) \ typedef ret(*name##_fn) args; \ static name##_fn p_##name; LUAJIT_SYMBOLS(DECLARE_LUAJIT_SYMBOL) static const char* LuaString(lua_State* L, int index) { const char* str = p_lua_tolstring(L, index, nullptr); if (str) return str; else return ""; } #ifdef _WIN32 static HMODULE luaLib; static void* Lua_LoadSymbol(const char* name) { void* p = (void*)GetProcAddress(luaLib, name); ASSERT(p, "missing symbol: %s", name); return p; } #else static void* luaLib; static void* Lua_LoadSymbol(const char* name) { void* p = dlsym(luaLib, name); ASSERT(p, "missing symbol: %s", name); return p; } #endif static lua_State* L; static void Lua_Bootstrap() { #if defined(_WIN32) luaLib = LoadLibraryA("lua51.dll"); #else luaLib = dlopen("libluajit-5.1.so", RTLD_NOW | RTLD_LOCAL); #endif ASSERT(luaLib); #define X(name, ret, args) \ p_##name = (name##_fn)Lua_LoadSymbol(#name); LUAJIT_SYMBOLS(X) #undef X L = p_luaL_newstate(); ASSERT(L); p_luaL_openlibs(L); } static lua_Integer Lua_GetInteger(lua_State* state, int index) { // ASSERT(p_lua_isinteger(state, index), "Lua argument is not an integer"); return p_lua_tointeger(state, index); } static byteview Lua_GetByteview(lua_State* state, int index) { size_t len = 0; const char* str = p_lua_tolstring(state, index, &len); ASSERT(str, "Lua argument is not a string"); return byteview { (uint8_t*)str, (uint64_t)len }; } static void Lua_BeginExport() { p_lua_createtable(L, 0, 3); } static void Lua_ExportFn(int (*fn)(lua_State*), const char* name) { p_lua_pushcclosure(L, (lua_CFunction)fn, 0); p_lua_setfield(L, -2, name); } static void Lua_EndExport(const char* name) { p_lua_setfield(L, LUA_GLOBALSINDEX, name); } static void Lua_ExecFile(const char* path) { int err = p_luaL_loadfile(L, path); if (err) { ASSERT(false, "luaL_loadfile('%s') failed: %s", path, LuaString(L, -1)); } err = p_lua_pcall(L, 0, LUA_MULTRET, 0); if (err) { ASSERT(false, "lua_pcall('%s') failed: %s", path, LuaString(L, -1)); } }