Created
February 20, 2025 16:57
-
-
Save actboy168/28df99cdea6ff015f8c51737214f9e03 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
local fs = require "bee.filesystem" | |
local code_main <const> = [[ | |
#include <lua.hpp> | |
static int push_preload_table(lua_State *L); | |
static int searcher(lua_State *L) { | |
const char *name = luaL_checkstring(L, 1); | |
lua_pushvalue(L, 1); | |
if (LUA_TNIL == lua_rawget(L, lua_upvalueindex(1))) { | |
lua_pushfstring(L, "no module '%s'", name); | |
return 1; | |
} | |
lua_call(L, 0, 1); | |
const char* str = lua_tostring(L, -1); | |
lua_Unsigned len = lua_rawlen(L, -1); | |
if (luaL_loadbuffer(L, str, (size_t)len, str) == LUA_OK) { | |
lua_pushstring(L, name); | |
return 2; | |
} | |
else { | |
return luaL_error(L, "error loading module '%s':\n\t%s", name, lua_tostring(L, -1)); | |
} | |
} | |
static int push_searcher(lua_State *L) { | |
push_preload_table(L); | |
lua_pushcclosure(L, searcher, 1); | |
return 1; | |
} | |
#define REG_SOURCE(module, name) \ | |
lua_pushlightuserdata(L, (void *)name); \ | |
lua_pushinteger(L, sizeof(name)); \ | |
lua_pushcclosure(L, get_string, 2); \ | |
lua_setfield(L, -2, module); | |
static int get_string(lua_State *L) { | |
const char* str = (const char *)lua_touserdata(L, lua_upvalueindex(1)); | |
size_t len = (size_t)lua_tointeger(L, lua_upvalueindex(2)); | |
lua_pushlstring(L, str, len); | |
return 1; | |
} | |
]] | |
local code_reg <const> = [[REG_SOURCE($module, $name)]] | |
local code_bin <const> = [[ | |
static const unsigned char $name[] = { | |
$bytes | |
}; | |
]] | |
local code_push <const> = [[ | |
static int push_preload_table(lua_State *L) { | |
lua_createtable(L, 0, $num); | |
$reg | |
return 1; | |
} | |
]] | |
local function readall(path) | |
local file <close> = assert(io.open(path, "rb")) | |
return file:read "a" | |
end | |
local function compile(content, symbol) | |
local count = 0 | |
local function tohex(c) | |
local b = string.format("0x%02x,", c:byte()) | |
count = count + 1 | |
if count == 16 then | |
b = b.."\n " | |
count = 0 | |
end | |
return b | |
end | |
local func = assert(load(content, "@"..symbol)) | |
local bin = string.dump(func) | |
return bin:gsub(".", tohex) | |
end | |
local function embed(file, list, content, symbol) | |
local cpp_symbol = "luasrc_"..symbol:match("^(.+)%.lua$"):gsub("/", "_") | |
list[#list+1] = code_reg:gsub("$(%w+)", { | |
name = cpp_symbol, | |
module = symbol:match("^(.+)%.lua$"):gsub("/", "."), | |
}) | |
local output = code_bin:gsub("$(%w+)", { | |
name = cpp_symbol, | |
bytes = compile(content, symbol), | |
}) | |
file:write(output) | |
file:write "\n" | |
end | |
local file <close> = assert(io.open("test.cpp", "wb")) | |
do | |
file:write(code_main) | |
file:write "\n" | |
end | |
local list = {} | |
for path, status in fs.pairs_r "scripts" do | |
if not status:is_directory() and path:extension() == ".lua" then | |
local filename = path:string() | |
local symbol = filename:sub(9) | |
embed(file, list, readall(filename), symbol) | |
end | |
end | |
embed(file, list, readall "main.lua", "main.lua") | |
do | |
local output = code_push:gsub("$(%w+)", { | |
num = #list, | |
reg = table.concat(list, "\n "), | |
}) | |
file:write(output) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment