feat(runtime): embed platform modules as bytecode

ui.lua and hints.lua are compiled to LUA_32BITS bytecode (matching the
firmware's Lua build) and linked into the binary. A new package.searchers
entry checks them as the fallback after the SD card, so a local
/.lua/lib/ui.lua still shadows the packaged one for debugging.

Bytecode is ~40% smaller than source and loads without parsing. A fresh
SD card with no make sdcard now has the platform available.
This commit is contained in:
2026-08-03 21:08:35 -04:00
parent 60ec720cdb
commit 6a9b082f97
10 changed files with 430 additions and 263 deletions
File diff suppressed because one or more lines are too long
+25 -4
View File
@@ -2,6 +2,9 @@
// mount, so every path into the filesystem goes through FsProvider instead.
#include <lua/runtime.h>
#include <lua/embedded_modules.h>
#include <cstring>
extern "C" {
#include "lauxlib.h"
@@ -82,6 +85,22 @@ int Runtime::searchModule(lua_State* state) {
return 1;
}
int Runtime::searchEmbedded(lua_State* state) {
const char* name = luaL_checkstring(state, 1);
for (size_t i = 0; i < embedded_modules_count; i++) {
if (std::strcmp(name, embedded_modules[i].name) != 0) continue;
const std::string chunkname = std::string("=") + name;
if (luaL_loadbuffer(state, reinterpret_cast<const char*>(embedded_modules[i].data),
embedded_modules[i].size, chunkname.c_str()) != LUA_OK) {
return luaL_error(state, "error loading embedded module '%s': %s", name, lua_tostring(state, -1));
}
lua_pushstring(state, name);
return 2;
}
lua_pushfstring(state, "\n\tno embedded module '%s'", name);
return 1;
}
int Runtime::loadFile(lua_State* state) {
Runtime* runtime = Runtime::from(state);
if (load(state, *runtime->providers_.fs, luaL_checkstring(state, 1)) == LUA_OK) return 1;
@@ -102,10 +121,12 @@ void Runtime::installLoader(const std::string& appDir) {
lua_getfield(state_, -1, "searchers");
lua_pushcfunction(state_, searchModule);
lua_rawseti(state_, -2, 2);
for (int at = 3; at <= 4; at++) {
lua_pushnil(state_);
lua_rawseti(state_, -2, at);
}
// Embedded bytecode is the fallback after the SD card, so a local /.lua/lib/ui.lua shadows
// the packaged one without reflashing.
lua_pushcfunction(state_, searchEmbedded);
lua_rawseti(state_, -2, 3);
lua_pushnil(state_);
lua_rawseti(state_, -2, 4);
lua_pop(state_, 2);
lua_pushcfunction(state_, loadFile);