From 81172006ae36db3d823b3cf972e6fd5ed6ff7fc2 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 11 Apr 2025 23:17:11 -0700 Subject: [PATCH 1/5] Various psyqo-lua fixes & improvements - proper cleaning cascading - adding pushv for resolving ambiguity - adding template to toUserdata - adding LUA_MULTRET default to call / pcall - refactored pcall to include a traceback - properly using bit32 for fixedpoint instead of bit - capturing newFromRaw locally for speedup - opening Lua libraries on vm creation - proper propagation of LUA_TARGET_PSX define --- src/mips/common.mk | 2 +- src/mips/psyqo-lua/Makefile | 1 + src/mips/psyqo-lua/examples/hello/hello.cpp | 22 ++++++++ src/mips/psyqo-lua/lua.hh | 14 +++-- src/mips/psyqo-lua/psyqo-lua.mk | 7 +-- src/mips/psyqo-lua/src/lua.cpp | 62 ++++++++++++++------- src/mips/psyqo-paths/psyqo-paths.mk | 4 +- src/mips/psyqo/psyqo.mk | 6 +- 8 files changed, 83 insertions(+), 35 deletions(-) diff --git a/src/mips/common.mk b/src/mips/common.mk index 3fb400c30..8a1ed7ab3 100644 --- a/src/mips/common.mk +++ b/src/mips/common.mk @@ -108,7 +108,7 @@ DEPS += $(patsubst %.s, %.dep,$(filter %.s,$(SRCS))) dep: $(DEPS) -clean: $(EXTRA_CLEAN) +clean:: rm -f $(OBJS) $(BINDIR)*.a $(BINDIR)Overlay.* $(BINDIR)*.elf $(BINDIR)*.ps-exe $(BINDIR)*.map $(DEPS) ifneq ($(MAKECMDGOALS), clean) diff --git a/src/mips/psyqo-lua/Makefile b/src/mips/psyqo-lua/Makefile index 003420366..f74d7aa37 100644 --- a/src/mips/psyqo-lua/Makefile +++ b/src/mips/psyqo-lua/Makefile @@ -7,6 +7,7 @@ SRCS = \ src/lua.cpp \ CPPFLAGS += -I$(PSYQOLUADIR)../../../third_party/psxlua/src +CPPFLAGS += -DLUA_TARGET_PSX EXTRA_DEPS += $(PSYQOLUADIR)Makefile diff --git a/src/mips/psyqo-lua/examples/hello/hello.cpp b/src/mips/psyqo-lua/examples/hello/hello.cpp index 16d5dbfd4..33ad7b68e 100644 --- a/src/mips/psyqo-lua/examples/hello/hello.cpp +++ b/src/mips/psyqo-lua/examples/hello/hello.cpp @@ -45,6 +45,12 @@ function factorial(n) end end +function printfactorial(n) + local f = factorial(n) + print('Factorial of ' .. tostring(n) .. ' is ' .. tostring(f)) + return f +end + -- Calculate some values results = { factorial = factorial(5), @@ -159,6 +165,8 @@ void LuaExample::createScene() { pushScene(&luaExampleScene); } +using namespace psyqo::fixed_point_literals; + void LuaExampleScene::frame() { auto& gpu = luaExample.gpu(); auto& font = luaExample.m_font; @@ -189,6 +197,20 @@ void LuaExampleScene::frame() { font.printf(gpu, {{.x = 16, .y = 144}}, textColor, "Calling factorial(7) from C++: %d", factorial7); } luaExample.L.pop(); + + // Example of using FixedPoint + luaExample.L.getGlobal("printfactorial"); + luaExample.L.push(6.0_fp); + if (luaExample.L.pcall(1, 1) != 0) { + // Error occurred + font.print(gpu, "Error calling printfactorial(6):", {{.x = 16, .y = 160}}, textColor); + font.print(gpu, luaExample.L.toString(-1), {{.x = 16, .y = 176}}, textColor); + } else { + auto factorial6 = luaExample.L.toFixedPoint(-1); + font.print(gpu, "Calling printfactorial(6.0_fp):", {{.x = 16, .y = 176}}, textColor); + font.printf(gpu, {{.x = 16, .y = 192}}, textColor, "Factorial(6) is %.2f", factorial6); + } + luaExample.L.pop(); } else { // Display error message font.print(gpu, "Lua script execution failed:", {{.x = 16, .y = 64}}, textColor); diff --git a/src/mips/psyqo-lua/lua.hh b/src/mips/psyqo-lua/lua.hh index 5e8d953d4..4883815fe 100644 --- a/src/mips/psyqo-lua/lua.hh +++ b/src/mips/psyqo-lua/lua.hh @@ -29,6 +29,7 @@ SOFTWARE. extern "C" { #include "lauxlib.h" #include "lua.h" +#include "lualib.h" } #include "EASTL/string_view.h" @@ -78,7 +79,8 @@ struct Lua { lua_pushlstring(L, s, S - 1); } void push(eastl::string_view s) { lua_pushlstring(L, s.data(), s.size()); } - void push(const char* fmt, ...); + void vpushf(const char* fmt, va_list ap) { lua_pushvfstring(L, fmt, ap); } + void pushf(const char* fmt, ...); void push(lua_CFunction f, int closure = 0) { lua_pushcclosure(L, f, closure); } void push(lua_CPPFunction f); void push(void* p) { lua_pushlightuserdata(L, p); } @@ -97,7 +99,10 @@ struct Lua { const char* toString(int idx, size_t* len = nullptr) { return lua_tolstring(L, idx, len); } size_t rawLen(int idx) { return lua_rawlen(L, idx); } lua_CFunction toCFunction(int idx) { return lua_tocfunction(L, idx); } - void* toUserdata(int idx) { return lua_touserdata(L, idx); } + template + T* toUserdata(int idx) { + return reinterpret_cast(lua_touserdata(L, idx)); + } lua_State* toThread(int idx) { return lua_tothread(L, idx); } const void* toPointer(int idx) { return lua_topointer(L, idx); } @@ -141,8 +146,8 @@ struct Lua { int setMetatable(int objindex) { return lua_setmetatable(L, objindex); } // Function calling - void call(int nargs, int nresults) { lua_call(L, nargs, nresults); } - int pcall(int nargs, int nresults, int errfunc = 0) { return lua_pcall(L, nargs, nresults, errfunc); } + void call(int nargs, int nresults = LUA_MULTRET) { lua_call(L, nargs, nresults); } + int pcall(int nargs, int nresults = LUA_MULTRET); // Loading and executing int loadBuffer(const char* buff, size_t sz, const char* chunkname = nullptr) { @@ -197,6 +202,7 @@ struct Lua { private: lua_State* L; void setupFixedPointMetatable(); + static int traceback(lua_State* L); }; } // namespace psyqo diff --git a/src/mips/psyqo-lua/psyqo-lua.mk b/src/mips/psyqo-lua/psyqo-lua.mk index b42dee670..440b8cd0a 100644 --- a/src/mips/psyqo-lua/psyqo-lua.mk +++ b/src/mips/psyqo-lua/psyqo-lua.mk @@ -4,14 +4,13 @@ PSYQOLUADIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) LIBRARIES += $(PSYQOLUADIR)libpsyqo-lua.a $(PSYQOLUADIR)../../../third_party/psxlua/src/liblua.a CPPFLAGS += -I$(PSYQOLUADIR)../../../third_party/psxlua/src +CPPFLAGS += -DLUA_TARGET_PSX LDFLAGS += \ -Wl,--defsym,luaI_sprintf=sprintf_for_Lua \ -Wl,--defsym,luaI_realloc=psyqo_realloc \ -Wl,--defsym,luaI_free=psyqo_free \ -EXTRA_CLEAN += clean-psyqo-lua - include $(PSYQOLUADIR)../psyqo/psyqo.mk $(PSYQOLUADIR)libpsyqo-lua.a: @@ -20,9 +19,9 @@ $(PSYQOLUADIR)libpsyqo-lua.a: $(PSYQOLUADIR)../../../third_party/psxlua/src/liblua.a: $(MAKE) -C $(PSYQOLUADIR)../../../third_party/psxlua/ psx -clean-psyqo-lua: +clean:: $(MAKE) -C $(PSYQOLUADIR) clean $(MAKE) -C $(PSYQOLUADIR)../../../third_party/psxlua/ clean -.PHONY: clean-psyqo-lua $(PSYQOLUADIR)libpsyqo-lua.a $(PSYQOLUADIR)../../../third_party/psxlua/src/liblua.a +.PHONY: clean $(PSYQOLUADIR)libpsyqo-lua.a $(PSYQOLUADIR)../../../third_party/psxlua/src/liblua.a endif diff --git a/src/mips/psyqo-lua/src/lua.cpp b/src/mips/psyqo-lua/src/lua.cpp index 512ea169a..5270d1a6d 100644 --- a/src/mips/psyqo-lua/src/lua.cpp +++ b/src/mips/psyqo-lua/src/lua.cpp @@ -26,6 +26,8 @@ SOFTWARE. #include "psyqo-lua/lua.hh" +#include + #include "psyqo/kernel.hh" #include "psyqo/xprintf.h" @@ -111,6 +113,7 @@ psyqo::FixedPoint<> psyqo::Lua::optFixedPoint(int idx, FixedPoint<> def) { psyqo::Lua::Lua() : L(luaL_newstate()) { static_assert(sizeof(Lua) == sizeof(lua_State*)); Kernel::assert(L, "Couldn't create Lua VM"); + luaL_openlibs(L); lua_atpanic(L, [](lua_State* L) -> int { const char* errorMsg = lua_tolstring(L, 1, nullptr); Kernel::abort(errorMsg); @@ -153,7 +156,7 @@ int psyqo::Lua::error(const char* fmt, ...) { return lua_error(L); } -void psyqo::Lua::push(const char* fmt, ...) { +void psyqo::Lua::pushf(const char* fmt, ...) { va_list argp; va_start(argp, fmt); lua_pushvfstring(L, fmt, argp); @@ -238,10 +241,10 @@ void psyqo::Lua::setupFixedPointMetatable() { unsigned fraction = raw & 0xfff; if (fraction == 0) { - L.push("%d", integer); + L.pushf("%d", integer); } else { unsigned decimal = (fraction * 1000) >> 12; - L.push("%d.%03u", integer, decimal); + L.pushf("%d.%03u", integer, decimal); } return 1; @@ -253,15 +256,22 @@ void psyqo::Lua::setupFixedPointMetatable() { return function(metatable) FixedPoint = metatable + -- Create a new FixedPoint from raw value + local newFromRaw = function(raw_value) + return setmetatable({_raw = raw_value}, FixedPoint) + end + + FixedPoint.newFromRaw = newFromRaw + -- Simple operations can be done directly in Lua function FixedPoint.__add(a, b) local raw_a = a._raw if type(b) == "number" then -- FixedPoint + number (treated as integer) - return FixedPoint.new(raw_a + bit.lshift(b, 12)) + return newFromRaw(raw_a + bit32.lshift(b, 12)) elseif type(b) == "table" and b._raw then -- FixedPoint + FixedPoint - return FixedPoint.new(raw_a + b._raw) + return newFromRaw(raw_a + b._raw) else error("Cannot add FixedPoint to this type") end @@ -271,10 +281,10 @@ void psyqo::Lua::setupFixedPointMetatable() { local raw_a = a._raw if type(b) == "number" then -- FixedPoint - number (treated as integer) - return FixedPoint.new(raw_a - bit.lshift(b, 12)) + return newFromRaw(raw_a - bit32.lshift(b, 12)) elseif type(b) == "table" and b._raw then -- FixedPoint - FixedPoint - return FixedPoint.new(raw_a - b._raw) + return newFromRaw(raw_a - b._raw) else error("Cannot subtract this type from FixedPoint") end @@ -282,7 +292,7 @@ void psyqo::Lua::setupFixedPointMetatable() { function FixedPoint.__unm(a) -- Unary minus - return FixedPoint.new(-a._raw) + return newFromRaw(-a._raw) end function FixedPoint.__eq(a, b) @@ -290,7 +300,7 @@ void psyqo::Lua::setupFixedPointMetatable() { return a._raw == b._raw elseif type(b) == "number" then -- Compare with an integer number (shifted) - return a._raw == bit.lshift(b, 12) + return a._raw == bit32.lshift(b, 12) else return false end @@ -301,7 +311,7 @@ void psyqo::Lua::setupFixedPointMetatable() { return a._raw < b._raw elseif type(b) == "number" then -- Compare with an integer number (shifted) - return a._raw < bit.lshift(b, 12) + return a._raw < bit32.lshift(b, 12) else error("Cannot compare FixedPoint with this type") end @@ -312,7 +322,7 @@ void psyqo::Lua::setupFixedPointMetatable() { return a._raw <= b._raw elseif type(b) == "number" then -- Compare with an integer number (shifted) - return a._raw <= bit.lshift(b, 12) + return a._raw <= bit32.lshift(b, 12) else error("Cannot compare FixedPoint with this type") end @@ -325,24 +335,19 @@ void psyqo::Lua::setupFixedPointMetatable() { -- Method to convert to a simple number (for simple calculations) function FixedPoint:toNumber() - return (self._raw + 2048) / 4096 - end - - -- Create a new FixedPoint from raw value - function FixedPoint.newFromRaw(raw_value) - return setmetatable({_raw = raw_value}, FixedPoint) + return bit32.rshift((self._raw + 2048), 12) end -- Create a new FixedPoint function FixedPoint.new(integer, fraction) if fraction == nil then fraction = 0 end - return setmetatable({_raw = bit.lshift(integer, 12) + fraction}, FixedPoint) + return setmetatable({_raw = bit32.lshift(integer, 12) + fraction}, FixedPoint) end end )lua"; // Load the Lua script - if (loadBuffer(fixedPointScript, sizeof(fixedPointScript) - 1) != 0) { + if (loadBuffer(fixedPointScript, sizeof(fixedPointScript) - 1, "buffer:fixedPointScript") != 0) { const char* errorMsg = toString(2); psyqo::Kernel::abort(errorMsg); } @@ -362,3 +367,22 @@ void psyqo::Lua::setupFixedPointMetatable() { pop(); } + +int psyqo::Lua::pcall(int nargs, int nresults) { + int n = getTop(); + int errorfunc = n - nargs; + lua_pushcfunction(L, traceback); + insert(errorfunc); + int r = lua_pcall(L, nargs, nresults, errorfunc); + remove(errorfunc); + return r; +} + +int psyqo::Lua::traceback(lua_State* L) { + int n = lua_gettop(L); + const char* msgPtr = n >= 1 ? lua_tostring(L, 1) : nullptr; + eastl::string msg = msgPtr ? msgPtr : "no message"; + lua_settop(L, 0); + luaL_traceback(L, L, msg.c_str(), 1); + return 1; +} diff --git a/src/mips/psyqo-paths/psyqo-paths.mk b/src/mips/psyqo-paths/psyqo-paths.mk index 0f11d8b64..e66731acc 100644 --- a/src/mips/psyqo-paths/psyqo-paths.mk +++ b/src/mips/psyqo-paths/psyqo-paths.mk @@ -3,14 +3,12 @@ PSYQOPATHSDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) LIBRARIES += $(PSYQOPATHSDIR)libpsyqo-paths.a -EXTRA_CLEAN += clean-psyqo-paths - include $(PSYQOPATHSDIR)../psyqo/psyqo.mk $(PSYQOPATHSDIR)libpsyqo-paths.a: $(MAKE) -C $(PSYQOPATHSDIR) BUILD=$(BUILD) -clean-psyqo-paths: +clean:: $(MAKE) -C $(PSYQOPATHSDIR) clean .PHONY: clean-psyqo-paths $(PSYQOPATHSDIR)libpsyqo-paths.a diff --git a/src/mips/psyqo/psyqo.mk b/src/mips/psyqo/psyqo.mk index 2bd003831..f92d52814 100644 --- a/src/mips/psyqo/psyqo.mk +++ b/src/mips/psyqo/psyqo.mk @@ -5,15 +5,13 @@ LIBRARIES += $(PSYQODIR)libpsyqo.a CPPFLAGS += -I$(PSYQODIR)../../../third_party/EASTL/include -I$(PSYQODIR)../../../third_party/EABase/include/Common CXXFLAGS += -std=c++20 -EXTRA_CLEAN += clean-psyqo - include $(PSYQODIR)../common.mk $(PSYQODIR)libpsyqo.a: $(MAKE) -C $(PSYQODIR) BUILD=$(BUILD) CPPFLAGS_$(BUILD)=$(CPPFLAGS_$(BUILD)) LDFLAGS_$(BUILD)=$(LDFLAGS_$(BUILD)) -clean-psyqo: +clean:: $(MAKE) -C $(PSYQODIR) clean -.PHONY: clean-psyqo $(PSYQODIR)libpsyqo.a +.PHONY: clean $(PSYQODIR)libpsyqo.a endif From bafe559249f1fe9d752eadd0441787f1dc10a9f5 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Fri, 11 Apr 2025 23:20:34 -0700 Subject: [PATCH 2/5] Building more psyqo examples at test time. --- .github/workflows/linux-toolchain.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux-toolchain.yml b/.github/workflows/linux-toolchain.yml index 2854bb7a5..d617d8662 100644 --- a/.github/workflows/linux-toolchain.yml +++ b/.github/workflows/linux-toolchain.yml @@ -26,4 +26,4 @@ jobs: - name: Build OpenBIOS with it run: make -C src/mips/openbios -j 6 all - name: Build psyqo examples with it - run: for d in src/mips/psyqo/examples/* ; do make -C $d -j 6 all TEST=true ; done + run: for d in src/mips/psyqo/examples/* src/mips/psyqo-paths/examples/* src/mips/psyqo-lua/examples/* ; do make -C $d -j 6 all TEST=true ; done From fab651f0d4b2ae8659369192fab2bf16299dcd09 Mon Sep 17 00:00:00 2001 From: Nicolas Noble Date: Fri, 11 Apr 2025 23:25:01 -0700 Subject: [PATCH 3/5] Clean up. Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/mips/psyqo-paths/psyqo-paths.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mips/psyqo-paths/psyqo-paths.mk b/src/mips/psyqo-paths/psyqo-paths.mk index e66731acc..09cca52b9 100644 --- a/src/mips/psyqo-paths/psyqo-paths.mk +++ b/src/mips/psyqo-paths/psyqo-paths.mk @@ -11,5 +11,5 @@ $(PSYQOPATHSDIR)libpsyqo-paths.a: clean:: $(MAKE) -C $(PSYQOPATHSDIR) clean -.PHONY: clean-psyqo-paths $(PSYQOPATHSDIR)libpsyqo-paths.a +.PHONY: clean $(PSYQOPATHSDIR)libpsyqo-paths.a endif From 77e5b281951926d6cdbb211c34b086650c83dfdb Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sat, 12 Apr 2025 06:10:44 -0700 Subject: [PATCH 4/5] Updating psxlua submodule. --- third_party/psxlua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/psxlua b/third_party/psxlua index 3439ab863..abed030e6 160000 --- a/third_party/psxlua +++ b/third_party/psxlua @@ -1 +1 @@ -Subproject commit 3439ab8636eaad7604572e6adc0921ae7caea53f +Subproject commit abed030e686b4e34987851bd0a028c93b1f73967 From e0e0fcf59f3914907556bacf4793c17c42f1afd2 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Sat, 12 Apr 2025 06:16:44 -0700 Subject: [PATCH 5/5] Some more optimizations in the FixedPoint Lua code. --- src/mips/psyqo-lua/src/lua.cpp | 51 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/mips/psyqo-lua/src/lua.cpp b/src/mips/psyqo-lua/src/lua.cpp index 5270d1a6d..96678e28a 100644 --- a/src/mips/psyqo-lua/src/lua.cpp +++ b/src/mips/psyqo-lua/src/lua.cpp @@ -262,31 +262,36 @@ void psyqo::Lua::setupFixedPointMetatable() { end FixedPoint.newFromRaw = newFromRaw + local lshift = bit32.lshift + local rshift = bit32.rshift + local err = function(op) + error('Cannot ' .. op .. ' FixedPoint to this type') + end -- Simple operations can be done directly in Lua function FixedPoint.__add(a, b) local raw_a = a._raw - if type(b) == "number" then - -- FixedPoint + number (treated as integer) - return newFromRaw(raw_a + bit32.lshift(b, 12)) - elseif type(b) == "table" and b._raw then + if type(b) == 'number' then + -- FixedPoint + number + return newFromRaw(raw_a + lshift(b, 12)) + elseif type(b) == 'table' and b._raw then -- FixedPoint + FixedPoint return newFromRaw(raw_a + b._raw) else - error("Cannot add FixedPoint to this type") + err('add') end end function FixedPoint.__sub(a, b) local raw_a = a._raw - if type(b) == "number" then - -- FixedPoint - number (treated as integer) - return newFromRaw(raw_a - bit32.lshift(b, 12)) - elseif type(b) == "table" and b._raw then + if type(b) == 'number' then + -- FixedPoint - number + return newFromRaw(raw_a - lshift(b, 12)) + elseif type(b) == 'table' and b._raw then -- FixedPoint - FixedPoint return newFromRaw(raw_a - b._raw) else - error("Cannot subtract this type from FixedPoint") + err('subtract') end end @@ -296,35 +301,35 @@ void psyqo::Lua::setupFixedPointMetatable() { end function FixedPoint.__eq(a, b) - if type(b) == "table" and b._raw then + if type(b) == 'table' and b._raw then return a._raw == b._raw - elseif type(b) == "number" then + elseif type(b) == 'number' then -- Compare with an integer number (shifted) - return a._raw == bit32.lshift(b, 12) + return a._raw == lshift(b, 12) else return false end end function FixedPoint.__lt(a, b) - if type(b) == "table" and b._raw then + if type(b) == 'table' and b._raw then return a._raw < b._raw - elseif type(b) == "number" then + elseif type(b) == 'number' then -- Compare with an integer number (shifted) - return a._raw < bit32.lshift(b, 12) + return a._raw < lshift(b, 12) else - error("Cannot compare FixedPoint with this type") + err('compare') end end function FixedPoint.__le(a, b) - if type(b) == "table" and b._raw then + if type(b) == 'table' and b._raw then return a._raw <= b._raw - elseif type(b) == "number" then + elseif type(b) == 'number' then -- Compare with an integer number (shifted) - return a._raw <= bit32.lshift(b, 12) + return a._raw <= lshift(b, 12) else - error("Cannot compare FixedPoint with this type") + err('compare') end end @@ -335,13 +340,13 @@ void psyqo::Lua::setupFixedPointMetatable() { -- Method to convert to a simple number (for simple calculations) function FixedPoint:toNumber() - return bit32.rshift((self._raw + 2048), 12) + return rshift((self._raw + 2048), 12) end -- Create a new FixedPoint function FixedPoint.new(integer, fraction) if fraction == nil then fraction = 0 end - return setmetatable({_raw = bit32.lshift(integer, 12) + fraction}, FixedPoint) + return setmetatable({_raw = lshift(integer, 12) + fraction}, FixedPoint) end end )lua";