Last active
November 6, 2025 19:23
-
-
Save ZumiKua/5b331840163b5a0308fc915ef9902adb to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| // luajittest.cpp : This file contains the 'main' function. Program execution begins and ends there. | |
| // | |
| #include <iostream> | |
| #include <string> | |
| #include "lua.hpp" | |
| #include "LuaJIT/src/lj_obj.h" | |
| #include "LuaJIT/src/lj_ctype.h" | |
| typedef struct { int a, b; } Object; | |
| Object* createObject() { | |
| printf("Create\n"); | |
| return new Object(); | |
| } | |
| bool deleted = false; | |
| void deleteObject(Object* ptr) { | |
| printf("Delete\n"); | |
| deleted = true; | |
| delete ptr; | |
| } | |
| typedef int (*callback_type)(int a); | |
| callback_type callback; | |
| void addCallback(int (*invoker)(int a)) { | |
| printf("Callback set\n"); | |
| callback = invoker; | |
| } | |
| #define REGISTER(L, s) registerSymbol(L, #s, s) | |
| static void registerSymbol(lua_State* L, const char* str, void* ptr) { | |
| lua_pushstring(L, str); | |
| lua_pushlightuserdata(L, ptr); | |
| lua_settable(L, -3); | |
| } | |
| void getfieldtable(lua_State* L, const char* name, int tableIdx) { | |
| lua_newtable(L); | |
| lua_pushstring(L, name); | |
| lua_pushvalue(L, -2); | |
| lua_settable(L, tableIdx); | |
| } | |
| static void registerAllSymbols(lua_State* L) { | |
| getfieldtable(L, "_CLIBS", LUA_REGISTRYINDEX); | |
| lua_pushstring(L, "TEST"); | |
| lua_newtable(L); | |
| REGISTER(L, createObject); | |
| REGISTER(L, deleteObject); | |
| REGISTER(L, addCallback); | |
| lua_settable(L, -3); | |
| lua_pop(L, 1); | |
| } | |
| void load(lua_State* L, const char* code, const char* name) { | |
| int top = lua_gettop(L); | |
| int status = luaL_loadbuffer(L, code, strlen(code), name); | |
| printf("%s", code); | |
| if (status) { | |
| throw std::runtime_error("Error loading lua string"); | |
| } | |
| int r = lua_pcall(L, 0, LUA_MULTRET, 0); | |
| int nresults = lua_gettop(L) - top; | |
| if (r != 0) { | |
| const char* str = lua_tostring(L, -1); | |
| printf("%s", str); | |
| } | |
| lua_pop(L, nresults); | |
| switch (r) { | |
| case LUA_OK: | |
| break; | |
| case LUA_ERRRUN: | |
| throw std::runtime_error("Runtime error while running LUA code."); | |
| case LUA_ERRMEM: | |
| throw std::runtime_error("Memory allocation error while running LUA code."); | |
| case LUA_ERRERR: | |
| throw std::runtime_error("Error in Error function."); | |
| case LUA_ERRSYNTAX: | |
| throw std::runtime_error("Syntax error in Lua code."); | |
| default: | |
| throw std::runtime_error(std::string("Unknow error while running LUA code (err code: ") + | |
| std::to_string(r) + ")"); | |
| } | |
| } | |
| int main() | |
| { | |
| static int lualoader = 1; | |
| lua_State* L = lua_open(); | |
| int n = lua_gettop(L); | |
| luaopen_ffi(L); | |
| lua_pushstring(L, "ffi"); | |
| lua_pushvalue(L, -2); | |
| lua_settable(L, LUA_GLOBALSINDEX); | |
| while (n < lua_gettop(L)) lua_pop(L, 1); | |
| static const char* test = ( | |
| #include "test.lua" | |
| ); | |
| registerAllSymbols(L); | |
| load(L, test, "src:test.lua"); | |
| printf("before %d\n", deleted); | |
| int i = 0; | |
| lua_State* delete_L = nullptr; | |
| while (i < 1000) { | |
| lua_State* newL = lua_newthread(L); | |
| printf("whild %d %d %x %x %x\n", i++, deleted, mref(G(L)->ctype_state, CTState)->L, L, newL); | |
| bool oldDeleted = deleted; | |
| if (luaL_dostring(newL, "local i = 1") != LUA_OK) { | |
| fprintf(stderr, "Error executing Lua code: %s\n", lua_tostring(L, -1)); | |
| } | |
| if (oldDeleted != deleted) { | |
| delete_L = newL; | |
| } | |
| } | |
| lua_gc(L, LUA_GCCOLLECT, 0); | |
| printf("Callback %d\n", callback(1)); | |
| printf("IsWhite %d\n", iswhite(obj2gco(delete_L))); | |
| printf("Finish\n"); | |
| lua_close(L); | |
| return 0; | |
| } |
This file contains hidden or 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
| -- lualoader, R"EOF(-- | |
| --print("Hello, World!") | |
| ffi.cdef [[ | |
| typedef struct { char opaque[?]; } Object; | |
| Object* createObject(); | |
| void deleteObject(Object*); | |
| void addCallback(int (*invoker)(int a)); | |
| ]] | |
| local C = ffi.load 'TEST' | |
| local function foo() | |
| local it = ffi.gc(C.createObject(), C.deleteObject); | |
| end | |
| local cb = function (num) | |
| local t = foo(); | |
| return num + 1 | |
| end | |
| foo(); | |
| C.addCallback(ffi.cast('int (*)(int a)', cb)) | |
| -- )EOF" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment