From 85bfb30b294fd0176879972b2761d134ddfcf7fc Mon Sep 17 00:00:00 2001 From: "saarsena@gmail.com" Date: Fri, 24 Apr 2026 22:09:12 -0400 Subject: [PATCH] Add godot-cpp submodule metadata --- .gitignore | 116 ++------------ .gitmodules | 4 + .sconsign.dblite | Bin 2211922 -> 2211922 bytes README.md | 102 ++++++++++++ SConstruct | 3 +- demo/test_runtime.gd | 76 ++++++++- src/onebit_lua_runtime.cpp | 308 ++++++++++++++++++++++++++++++++++--- src/onebit_lua_runtime.h | 14 ++ src/onebit_lua_runtime.os | Bin 115672 -> 127336 bytes src/register_types.cpp | 1 + src/register_types.os | Bin 62928 -> 62928 bytes src/samq2.code-workspace | 13 ++ 12 files changed, 516 insertions(+), 121 deletions(-) create mode 100644 .gitmodules create mode 100644 README.md create mode 100644 src/samq2.code-workspace diff --git a/.gitignore b/.gitignore index df2503c..bdf4baa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,108 +1,26 @@ -# ----------------- # -# Godot 4+ specific # -# ----------------- # - -# This is the most important folder to ignore. It contains the project's cache, -# imported asset data, and other generated files. It will be regenerated -# automatically by the editor. Committing it will bloat the repository and -# cause constant merge conflicts. +# Godot/editor cache .godot/ -.claude -.vscode -backup +.godot-home/ +demo/.godot/ -# Ignore user-specific editor settings. -# These files save the state of your editor (window layout, last open scenes, etc.) -# and should not be shared with the team. -.godot/editor/ -editor_layout.cfg -command_system_guide.md -*.md +# SCons and native build output +.sconsign.dblite +*.os +*.o +*.a +*.so +*.dll +*.dylib +*.framework/ +demo/addons/onebit_lua/bin/ +godot-cpp/bin/ +godot-cpp/gen/ -# ------------- # -# C# / .NET # -# ------------- # - -# Ignore the .mono directory, which contains Mono-related build files and cache for Godot 3.x. -# For Godot 4.x with .NET 6+, these files are typically inside .godot/mono -.mono/ - -# Ignore generated build artifacts from dotnet/MSBuild. -bin/ -obj/ - -# Ignore user-specific C# project files created by IDEs like Visual Studio or Rider. -*.csproj.user -*.sln.DotSettings.user - - -# -------------------------- # -# Exported Builds & Templates # -# -------------------------- # - -# Ignore directories where you might store exported builds of your game. -builds/ -export/ -exports/ - -# Ignore the actual exported game files, regardless of where they are. -*.pck -*.exe -*.AppImage -*.html -*.wasm -*.apk -*.aab - -# Ignore export templates, which are large and can be downloaded by any developer. -# You typically don't want these in your repository. -export_templates/ -templates/ -*.zip -*.tpz - - -# ----------------------------------- # -# IDE / Text Editor Specific Settings # -# ----------------------------------- # - -# Visual Studio Code +# Editor/OS noise .vscode/ - -# JetBrains Rider / IntelliJ .idea/ - -# Visual Studio -.vs/ - - -# ---------------- # -# OS Specific # -# ---------------- # - -# macOS .DS_Store -.AppleDouble -.LSOverride - -# Windows Thumbs.db -ehthumbs.db -Desktop.ini - -# ---------------- # -# Other Common # -# ---------------- # - -# Log files -debug_log.txt +# Logs *.log -turn_system_plan.md - -# Asset pack archives (you should unpack them and commit the assets, not the zip) -*.rar -*.7z - - -.CLAUDE.md diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..35ec1da --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "godot-cpp"] + path = godot-cpp + url = https://github.com/godotengine/godot-cpp.git + branch = master diff --git a/.sconsign.dblite b/.sconsign.dblite index 080eafb60c90986d1b1e6810334a49f14a6a308d..9cd0717d108946b36eca06fd7211f5c6f1b66ebc 100644 GIT binary patch delta 754 zcmaiyO-NKx6vrK%)bYEf8B5DM_F)Mr_v5{H-vgtdO^z6~D1y|y_q{v484wC}lN2Hc z+z2fixQp6UCVeamEQ&}1+m@}`M4N&@f);`hME7bztz6t6|HI)N&i|adGCiAEF>e|Y zPzhC#gl$j_HBbvFsDpZFfJSJ7W@v%!umjSt6Ecv6R@eo*p$*z$5A21GrzpmKZa^HO zT;(annexJjh=_-rW4{o3fse~`sfps48lMnjm&^GlhgXYp$?@VGOOQO`Dk+!NkkjlTSAC72>yN_-r%PvT z`n*klE45gi)~zGxOhYMQgQP``o*6;Qna5VYw76q&*W#W&brG#q-?Dm6_m85n%xkNc zEN)vow0NYKN6|?Ayw&$D7W4^$ydD`9BsX4^@|B>Ta3Z2qBx&S1jC&rowq9)5$;Urt z7X&gdx40lWuU$C0W$l00wO#&P*R)FL&!b7yv-MUpW~*kK*}->fH{UmR>!~ZbMm=>S z>FNj9QRCu)SDoJz$IThS5C?)5lf!x(^Wc5V_r10G#rRrO z^ALw7XodvrfF!g)E2Lm2?1J5phBj!24D5lu&;gy$1>MjC`(Qt0p%)IoLFjvoLOf;~ z6f??Pj)lRgE169^$0Dv{abj9n)~czQsfwJQ@hTTWZx8KO9rb82KYo zQsQtSgMd)i#g;ILz+S)v4{STTXJW}sV zsEBUs{;tNd#yyR?#tV%Vb<#ujh%f>y?LhiQKz-l!9l|l@*mZ0xFd5qnYiZL??%nEQ z-9u6JH|pNN)$_-<-Tm*nTIKI`BdNIhSW5H{ZyRb?6lxS^cmDPIjW_K>YVJ~hTFqTg zSnB>Ylx_?@ANU?WVG7BGBWzB5Dhc(tZwi~*!gnK6UchVNmQ3zPXKyU*Io&kN|8RP= HHaq$o0;TSu diff --git a/README.md b/README.md new file mode 100644 index 0000000..080afeb --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# OneBit Lua Runtime + +Native GDExtension prototype for the 1BitRL v2 Lua runtime contract. + +## Current Scope + +This runtime is intentionally small and breaking: + +- `api_version = 2` scripts only. +- No `game` table. +- Explicit `ctx` and `state` handler arguments. +- Lua emits commands and logs; it does not mutate the Godot world directly. +- Queries cross a Godot-owned query host boundary. +- Instruction budget is enabled for handler calls. + +Initial Lua API: + +```lua +sense.is_walkable(x, y) +sense.find_nearest(group) +move.step(dx, dy) +log.say(message, duration) +``` + +## Requirements + +- Godot 4.6. +- `godot-cpp` master, targeting `api_version=4.6`. +- SCons. +- A Lua development package with `pkg-config`. + +This machine currently uses Lua 5.1: + +```sh +pkg-config lua-5.1 --cflags --libs +``` + +Lua 5.1 is explicit for now because it is the installed system package. If the project moves to Lua 5.4, install a Lua 5.4 development package and build with the matching pkg-config name, for example: + +```sh +scons platform=linux target=template_debug api_version=4.6 lua_pkg=lua5.4 +``` + +Script semantics differ between Lua 5.1 and 5.4, so do not change the runtime version silently. + +## Build + +Clone `godot-cpp` as a submodule or checkout at `godot-cpp/`, then run: + +```sh +scons platform=linux target=template_debug api_version=4.6 -j4 +``` + +The demo extension library is written to: + +```text +demo/addons/onebit_lua/bin/ +``` + +## Smoke Test + +Run the demo project headlessly: + +```sh +godot --headless --path demo +``` + +Expected behavior: + +- Loads `OneBitLuaRuntime`. +- Loads a tiny `api_version = 2` script. +- Calls `on_update(ctx, state)`. +- Mutates `state.count`. +- Emits one `move` command. +- Emits one log entry. +- Calls the GDScript query host for `sense.is_walkable` and `sense.find_nearest`. + +## Safe Lua Libraries + +The runtime opens only selected Lua libraries: + +- base +- math +- string +- table + +It does not open: + +- `io` +- `os` +- `package` +- `debug` + +After opening the base library, the runtime removes dangerous dynamic-loading globals: + +- `dofile` +- `load` +- `loadfile` +- `loadstring` +- `module` +- `require` +- `collectgarbage` diff --git a/SConstruct b/SConstruct index 3191f01..aa2d7b9 100644 --- a/SConstruct +++ b/SConstruct @@ -3,7 +3,8 @@ env = SConscript("godot-cpp/SConstruct") env.Append(CPPPATH=["src"]) -env.ParseConfig("pkg-config lua-5.1 --cflags --libs") +lua_pkg = ARGUMENTS.get("lua_pkg", "lua-5.1") +env.ParseConfig("pkg-config {} --cflags --libs".format(lua_pkg)) sources = Glob("src/*.cpp") diff --git a/demo/test_runtime.gd b/demo/test_runtime.gd index 059c9d5..0637bf5 100644 --- a/demo/test_runtime.gd +++ b/demo/test_runtime.gd @@ -36,10 +36,12 @@ return { on_update = function(ctx, state) state.count = (state.count or 0) + 1 + state.world_x = ctx.self.world.x + state.tint_r = ctx.self.tint.r if not ctx.self.is_moving and sense.is_walkable(2, 3) then local nearest = sense.find_nearest("players") move.step(1, 0) - log.say("tick", 1.0) + log.say("tick " .. tostring(state.count) .. " target " .. tostring(nearest.entity_id), 1.0) end end } @@ -52,6 +54,8 @@ return { var ctx := { "self": { "is_moving": false, + "world": Vector2(2.0, 3.0), + "tint": Color(0.25, 0.5, 0.75, 1.0), }, } var state := {} @@ -61,10 +65,78 @@ return { get_tree().quit(1) return - if result.commands.size() != 1 or result.logs.size() != 1 or result.state.get("count", 0) != 1: + if result.commands.size() != 1 or result.logs.size() != 1 or result.state.get("count", 0) != 1 or result.state.get("world_x", 0) != 2 or result.state.get("tint_r", 0) != 0.25 or result.logs[0].message != "tick 1 target 7": push_error("unexpected result: " + str(result)) get_tree().quit(1) return + if not _expect_runtime_error(""" +return { + api_version = 2, + on_update = function(ctx, state) + sense.is_walkable = function() return true end + end +} +""", "read-only"): + get_tree().quit(1) + return + + if not _expect_runtime_error(""" +return { + api_version = 2, + on_update = function(ctx, state) + sense = nil + end +} +""", "globals are read-only"): + get_tree().quit(1) + return + + var mem_rt := OneBitLuaRuntime.new() + mem_rt.set_entity_id(42) + mem_rt.set_query_host(query_host) + mem_rt.set_instruction_budget(1000000) + mem_rt.set_memory_budget(1024 * 1024) + var mem_loaded := mem_rt.load_string(""" +return { + api_version = 2, + on_update = function(ctx, state) + local chunks = {} + for i = 1, 10000 do + chunks[i] = string.rep("x", 4000) .. tostring(i) + end + state.done = true + end +} +""") + if not mem_loaded.ok: + push_error("memory test failed to load: " + str(mem_loaded.error)) + get_tree().quit(1) + return + var mem_result := mem_rt.call_event("on_update", ctx, {}, []) + if mem_result.ok or not str(mem_result.error).contains("memory budget"): + push_error("memory budget test did not fail as expected: " + str(mem_result)) + get_tree().quit(1) + return + print("OneBitLuaRuntime smoke test passed: ", result) get_tree().quit(0) + + +func _expect_runtime_error(source: String, expected_error: String) -> bool: + var rt := OneBitLuaRuntime.new() + rt.set_entity_id(42) + rt.set_query_host(query_host) + var loaded := rt.load_string(source) + if not loaded.ok: + push_error("expected load success, got: " + str(loaded.error)) + return false + + var result := rt.call_event("on_update", {"self": {"is_moving": false}}, {}, []) + if result.ok: + push_error("expected runtime error, got success: " + str(result)) + return false + if not str(result.error).contains(expected_error) or not str(result.error).contains("[string \"\"]"): + push_error("unexpected runtime error: " + str(result.error)) + return false + return true diff --git a/src/onebit_lua_runtime.cpp b/src/onebit_lua_runtime.cpp index 429be15..3617670 100644 --- a/src/onebit_lua_runtime.cpp +++ b/src/onebit_lua_runtime.cpp @@ -3,8 +3,13 @@ #include #include #include +#include #include +#include #include +#include + +#include extern "C" { #include @@ -15,6 +20,8 @@ extern "C" { #define LUA_OK 0 #endif +static const char *ONEBIT_RUNTIME_REGISTRY_KEY = "onebit_lua_runtime"; + using namespace godot; void OneBitLuaRuntime::_bind_methods() { @@ -24,6 +31,7 @@ void OneBitLuaRuntime::_bind_methods() { ClassDB::bind_method(D_METHOD("set_entity_id", "entity_id"), &OneBitLuaRuntime::set_entity_id); ClassDB::bind_method(D_METHOD("set_query_host", "host"), &OneBitLuaRuntime::set_query_host); ClassDB::bind_method(D_METHOD("set_instruction_budget", "budget"), &OneBitLuaRuntime::set_instruction_budget); + ClassDB::bind_method(D_METHOD("set_memory_budget", "bytes"), &OneBitLuaRuntime::set_memory_budget); } OneBitLuaRuntime::OneBitLuaRuntime() { @@ -31,21 +39,69 @@ OneBitLuaRuntime::OneBitLuaRuntime() { } OneBitLuaRuntime::~OneBitLuaRuntime() { - _reset_lua(); + _close_lua(); } -void OneBitLuaRuntime::_reset_lua() { +void OneBitLuaRuntime::_close_lua() { if (lua) { _clear_handlers(); lua_close(lua); lua = nullptr; } +} - lua = luaL_newstate(); +void OneBitLuaRuntime::_reset_lua() { + _close_lua(); + + memory_used_bytes = 0; instruction_budget_exceeded = false; + memory_budget_exceeded = false; + lua = lua_newstate(&OneBitLuaRuntime::_lua_allocator, this); + if (!lua) { + memory_budget_exceeded = true; + return; + } + _open_safe_libraries(); _install_api(); } +void OneBitLuaRuntime::_open_safe_libraries() { + struct SafeLib { + const char *name; + lua_CFunction open; + }; + + const SafeLib safe_libs[] = { + { "", luaopen_base }, + { LUA_MATHLIBNAME, luaopen_math }, + { LUA_STRLIBNAME, luaopen_string }, + { LUA_TABLIBNAME, luaopen_table }, + { nullptr, nullptr }, + }; + + for (const SafeLib *lib = safe_libs; lib->open; lib++) { + lua_pushcfunction(lua, lib->open); + lua_pushstring(lua, lib->name); + lua_call(lua, 1, 0); + } + + const char *blocked_globals[] = { + "dofile", + "load", + "loadfile", + "loadstring", + "module", + "require", + "collectgarbage", + nullptr, + }; + + for (const char **name = blocked_globals; *name; name++) { + lua_pushnil(lua); + lua_setglobal(lua, *name); + } +} + void OneBitLuaRuntime::_clear_handlers() { if (!lua) { handlers.clear(); @@ -60,7 +116,7 @@ void OneBitLuaRuntime::_clear_handlers() { void OneBitLuaRuntime::_install_api() { lua_pushlightuserdata(lua, this); - lua_setglobal(lua, "__onebit_runtime"); + lua_setfield(lua, LUA_REGISTRYINDEX, ONEBIT_RUNTIME_REGISTRY_KEY); lua_newtable(lua); lua_pushlightuserdata(lua, this); @@ -69,19 +125,52 @@ void OneBitLuaRuntime::_install_api() { lua_pushlightuserdata(lua, this); lua_pushcclosure(lua, &OneBitLuaRuntime::_lua_sense_find_nearest, 1); lua_setfield(lua, -2, "find_nearest"); - lua_setglobal(lua, "sense"); + _set_readonly_global("sense"); lua_newtable(lua); lua_pushlightuserdata(lua, this); lua_pushcclosure(lua, &OneBitLuaRuntime::_lua_move_step, 1); lua_setfield(lua, -2, "step"); - lua_setglobal(lua, "move"); + _set_readonly_global("move"); lua_newtable(lua); lua_pushlightuserdata(lua, this); lua_pushcclosure(lua, &OneBitLuaRuntime::_lua_log_say, 1); lua_setfield(lua, -2, "say"); - lua_setglobal(lua, "log"); + _set_readonly_global("log"); +} + +void OneBitLuaRuntime::_set_readonly_global(const char *name) { + int api_table = lua_gettop(lua); + + lua_newtable(lua); + int proxy_table = lua_gettop(lua); + + lua_newtable(lua); + lua_pushvalue(lua, api_table); + lua_setfield(lua, -2, "__index"); + lua_pushcfunction(lua, &OneBitLuaRuntime::_lua_readonly_error); + lua_setfield(lua, -2, "__newindex"); + lua_pushboolean(lua, 0); + lua_setfield(lua, -2, "__metatable"); + lua_setmetatable(lua, proxy_table); + + lua_setglobal(lua, name); + lua_pop(lua, 1); +} + +void OneBitLuaRuntime::_push_script_environment() { + lua_newtable(lua); + int env_table = lua_gettop(lua); + + lua_newtable(lua); + lua_pushvalue(lua, LUA_GLOBALSINDEX); + lua_setfield(lua, -2, "__index"); + lua_pushcfunction(lua, &OneBitLuaRuntime::_lua_global_write_error); + lua_setfield(lua, -2, "__newindex"); + lua_pushboolean(lua, 0); + lua_setfield(lua, -2, "__metatable"); + lua_setmetatable(lua, env_table); } Dictionary OneBitLuaRuntime::_base_result(bool ok, const String &error) const { @@ -99,23 +188,51 @@ Dictionary OneBitLuaRuntime::_error_result(const String &error) const { return _base_result(false, error); } +String OneBitLuaRuntime::_pop_lua_error() { + String error; + if (lua && lua_gettop(lua) > 0 && lua_isstring(lua, -1)) { + error = String(lua_tostring(lua, -1)); + } else { + error = "Unknown Lua error"; + } + if (lua && lua_gettop(lua) > 0) { + lua_pop(lua, 1); + } + return error; +} + Dictionary OneBitLuaRuntime::load_string(const String &source) { + return _load_source(source, ""); +} + +Dictionary OneBitLuaRuntime::_load_source(const String &source, const String &source_name) { _reset_lua(); commands.clear(); logs.clear(); - CharString utf8 = source.utf8(); - if (luaL_loadstring(lua, utf8.get_data()) != LUA_OK) { - String error = String(lua_tostring(lua, -1)); - lua_pop(lua, 1); - return _error_result(error); + if (!lua) { + return _error_result("Failed to create Lua state"); } - if (lua_pcall(lua, 0, 1, 0) != LUA_OK) { - String error = String(lua_tostring(lua, -1)); - lua_pop(lua, 1); + CharString utf8 = source.utf8(); + CharString source_name_utf8 = source_name.utf8(); + if (luaL_loadbuffer(lua, utf8.get_data(), utf8.length(), source_name_utf8.get_data()) != LUA_OK) { + return _error_result(_pop_lua_error()); + } + + _push_script_environment(); + lua_setfenv(lua, -2); + + lua_pushcfunction(lua, &OneBitLuaRuntime::_traceback_handler); + lua_insert(lua, -2); + int error_handler = lua_gettop(lua) - 1; + + if (lua_pcall(lua, 0, 1, error_handler) != LUA_OK) { + String error = _pop_lua_error(); + lua_remove(lua, error_handler); return _error_result(error); } + lua_remove(lua, error_handler); if (!lua_istable(lua, -1)) { lua_pop(lua, 1); @@ -134,7 +251,7 @@ Dictionary OneBitLuaRuntime::load_script(const String &path) { } String source = file->get_as_text(); - return load_string(source); + return _load_source(source, path); } Dictionary OneBitLuaRuntime::_extract_handlers(int table_index, const String &source_name) { @@ -191,16 +308,27 @@ Dictionary OneBitLuaRuntime::call_event(const String &event_name, const Dictiona _push_variant(args[i]); } + int function_index = lua_gettop(lua) - (2 + int(args.size())); + lua_pushcfunction(lua, &OneBitLuaRuntime::_traceback_handler); + lua_insert(lua, function_index); + int error_handler = function_index; + lua_sethook(lua, &OneBitLuaRuntime::_instruction_hook, LUA_MASKCOUNT, int(instruction_budget)); int status = lua_pcall(lua, 2 + int(args.size()), 0, 0); lua_sethook(lua, nullptr, 0, 0); if (status != LUA_OK) { - String error = instruction_budget_exceeded ? String("Lua instruction budget exceeded") : String(lua_tostring(lua, -1)); - lua_pop(lua, 1); + String error = _pop_lua_error(); + if (instruction_budget_exceeded) { + error = "Lua instruction budget exceeded\n" + error; + } else if (memory_budget_exceeded) { + error = "Lua memory budget exceeded\n" + error; + } + lua_remove(lua, error_handler); luaL_unref(lua, LUA_REGISTRYINDEX, state_ref); return _error_result(error); } + lua_remove(lua, error_handler); lua_rawgeti(lua, LUA_REGISTRYINDEX, state_ref); Variant updated_state = _read_lua_value(-1); @@ -226,10 +354,74 @@ void OneBitLuaRuntime::set_instruction_budget(int64_t p_budget) { instruction_budget = p_budget > 0 ? p_budget : 1; } +void OneBitLuaRuntime::set_memory_budget(int64_t p_bytes) { + memory_budget_bytes = p_bytes > 0 ? p_bytes : 1; +} + +void *OneBitLuaRuntime::_lua_allocator(void *ud, void *ptr, size_t osize, size_t nsize) { + (void)osize; + OneBitLuaRuntime *runtime = static_cast(ud); + const size_t header_size = sizeof(size_t); + + if (nsize == 0) { + if (runtime) { + if (ptr) { + void *base_ptr = static_cast(ptr) - header_size; + size_t old_size = *static_cast(base_ptr); + runtime->memory_used_bytes -= int64_t(old_size); + std::free(base_ptr); + } + if (runtime->memory_used_bytes < 0) { + runtime->memory_used_bytes = 0; + } + } else if (ptr) { + std::free(static_cast(ptr) - header_size); + } + return nullptr; + } + + if (!runtime) { + void *base_ptr = ptr ? static_cast(ptr) - header_size : nullptr; + void *new_base = std::realloc(base_ptr, nsize + header_size); + if (!new_base) { + return nullptr; + } + *static_cast(new_base) = nsize; + return static_cast(new_base) + header_size; + } + + size_t old_raw_size = 0; + void *base_ptr = nullptr; + if (ptr) { + base_ptr = static_cast(ptr) - header_size; + old_raw_size = *static_cast(base_ptr); + } + + int64_t old_size = int64_t(old_raw_size); + int64_t new_size = int64_t(nsize); + int64_t delta = new_size - old_size; + if (delta > 0 && runtime->memory_used_bytes + delta > runtime->memory_budget_bytes) { + runtime->memory_budget_exceeded = true; + return nullptr; + } + + void *new_base = std::realloc(base_ptr, nsize + header_size); + if (!new_base) { + return nullptr; + } + *static_cast(new_base) = nsize; + + runtime->memory_used_bytes += delta; + if (runtime->memory_used_bytes < 0) { + runtime->memory_used_bytes = 0; + } + return static_cast(new_base) + header_size; +} + void OneBitLuaRuntime::_instruction_hook(lua_State *L, lua_Debug *debug) { (void)debug; OneBitLuaRuntime *runtime = nullptr; - lua_getglobal(L, "__onebit_runtime"); + lua_getfield(L, LUA_REGISTRYINDEX, ONEBIT_RUNTIME_REGISTRY_KEY); if (lua_islightuserdata(L, -1)) { runtime = static_cast(lua_touserdata(L, -1)); } @@ -241,6 +433,51 @@ void OneBitLuaRuntime::_instruction_hook(lua_State *L, lua_Debug *debug) { luaL_error(L, "Lua instruction budget exceeded"); } +int OneBitLuaRuntime::_lua_readonly_error(lua_State *L) { + const char *key = lua_tostring(L, 2); + if (!key) { + key = ""; + } + return luaL_error(L, "Lua API tables are read-only: cannot assign '%s'", key); +} + +int OneBitLuaRuntime::_lua_global_write_error(lua_State *L) { + const char *key = lua_tostring(L, 2); + if (!key) { + key = ""; + } + return luaL_error(L, "Lua globals are read-only: attempted to assign '%s'", key); +} + +int OneBitLuaRuntime::_traceback_handler(lua_State *L) { + const char *message = lua_tostring(L, 1); + if (!message) { + message = "Unknown Lua error"; + } + + luaL_Buffer buffer; + luaL_buffinit(L, &buffer); + luaL_addstring(&buffer, message); + luaL_addstring(&buffer, "\nstack traceback:"); + + lua_Debug ar; + int level = 1; + while (lua_getstack(L, level, &ar)) { + lua_getinfo(L, "Sln", &ar); + luaL_addstring(&buffer, "\n "); + luaL_addstring(&buffer, ar.short_src ? ar.short_src : ""); + luaL_addstring(&buffer, ":"); + CharString line = String::num_int64(ar.currentline).utf8(); + luaL_addstring(&buffer, line.get_data()); + luaL_addstring(&buffer, ": in "); + luaL_addstring(&buffer, ar.name ? ar.name : "?"); + level++; + } + + luaL_pushresult(&buffer); + return 1; +} + Variant OneBitLuaRuntime::_query(const String &query_name, const Dictionary ¶ms) { if (query_host_id == 0) { return Variant(); @@ -329,6 +566,15 @@ bool OneBitLuaRuntime::_push_variant(const Variant &value) { lua_pushstring(lua, utf8.get_data()); return true; } + case Variant::VECTOR2: { + Vector2 vector = value; + lua_newtable(lua); + lua_pushnumber(lua, vector.x); + lua_setfield(lua, -2, "x"); + lua_pushnumber(lua, vector.y); + lua_setfield(lua, -2, "y"); + return true; + } case Variant::VECTOR2I: { Vector2i vector = value; lua_newtable(lua); @@ -338,6 +584,30 @@ bool OneBitLuaRuntime::_push_variant(const Variant &value) { lua_setfield(lua, -2, "y"); return true; } + case Variant::VECTOR3: { + Vector3 vector = value; + lua_newtable(lua); + lua_pushnumber(lua, vector.x); + lua_setfield(lua, -2, "x"); + lua_pushnumber(lua, vector.y); + lua_setfield(lua, -2, "y"); + lua_pushnumber(lua, vector.z); + lua_setfield(lua, -2, "z"); + return true; + } + case Variant::COLOR: { + Color color = value; + lua_newtable(lua); + lua_pushnumber(lua, color.r); + lua_setfield(lua, -2, "r"); + lua_pushnumber(lua, color.g); + lua_setfield(lua, -2, "g"); + lua_pushnumber(lua, color.b); + lua_setfield(lua, -2, "b"); + lua_pushnumber(lua, color.a); + lua_setfield(lua, -2, "a"); + return true; + } case Variant::DICTIONARY: { Dictionary dict = value; lua_newtable(lua); diff --git a/src/onebit_lua_runtime.h b/src/onebit_lua_runtime.h index bfd11f8..4f0eec6 100644 --- a/src/onebit_lua_runtime.h +++ b/src/onebit_lua_runtime.h @@ -27,7 +27,10 @@ private: int64_t entity_id = 0; uint64_t query_host_id = 0; int64_t instruction_budget = 100000; + int64_t memory_budget_bytes = 16 * 1024 * 1024; + int64_t memory_used_bytes = 0; bool instruction_budget_exceeded = false; + bool memory_budget_exceeded = false; static void _bind_methods(); @@ -35,11 +38,21 @@ private: static int _lua_log_say(lua_State *L); static int _lua_sense_is_walkable(lua_State *L); static int _lua_sense_find_nearest(lua_State *L); + static int _lua_readonly_error(lua_State *L); + static int _lua_global_write_error(lua_State *L); + static int _traceback_handler(lua_State *L); static void _instruction_hook(lua_State *L, lua_Debug *debug); + static void *_lua_allocator(void *ud, void *ptr, size_t osize, size_t nsize); + void _close_lua(); void _reset_lua(); + void _open_safe_libraries(); void _install_api(); + void _set_readonly_global(const char *name); + void _push_script_environment(); void _clear_handlers(); + Dictionary _load_source(const String &source, const String &source_name); + String _pop_lua_error(); Dictionary _base_result(bool ok, const String &error = "") const; Dictionary _error_result(const String &error) const; Variant _query(const String &query_name, const Dictionary ¶ms); @@ -60,6 +73,7 @@ public: void set_entity_id(int64_t p_entity_id); void set_query_host(Object *p_host); void set_instruction_budget(int64_t p_budget); + void set_memory_budget(int64_t p_bytes); }; #endif diff --git a/src/onebit_lua_runtime.os b/src/onebit_lua_runtime.os index 178190f7427bb93db8722025025f2554ef5ad00f..3ae42f1b8e04ac0660e9d80302d1b8313f0d2940 100644 GIT binary patch literal 127336 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 AlK=n! literal 115672 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 diff --git a/src/register_types.cpp b/src/register_types.cpp index a55aca3..5854218 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -30,6 +30,7 @@ GDExtensionBool GDE_EXPORT onebit_lua_library_init( godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); init_obj.register_initializer(initialize_onebit_lua_module); + init_obj.register_terminator(uninitialize_onebit_lua_module); init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); diff --git a/src/register_types.os b/src/register_types.os index 9160d44e17f755c2ad73c105ddc7d2b5e055b257..e8b752c9ad4c3668121705eda02f60f689bb722e 100644 GIT binary patch delta 23 ecmcccn)$+O<_$|Z89O#F