From 40c539bf22f504b46945455dcd5e49aef4ebc132 Mon Sep 17 00:00:00 2001 From: modeco80 Date: Thu, 27 Jul 2023 06:03:28 -0400 Subject: [PATCH] lcpu: Lua devices now work!! now i can like, actually finish this thing i will probably commonize all the stuff the luadevice class is doing right now into its own object, since I think that it would be very useful to have elsewhere. but for now it's not common :( --- lua/autorun/lcpu_load.lua | 50 ++++- lua/entities/gmod_lcpu_cpu.lua | 43 ++-- native/projects/lcpu/CMakeLists.txt | 2 +- native/projects/lcpu/src/LcpuGlobals.cpp | 11 +- native/projects/lcpu/src/LuaCpu.cpp | 7 +- native/projects/lcpu/src/LuaDevice.cpp | 201 ++++++++++++------ native/projects/lcpu/src/LuaDevice.hpp | 13 +- native/projects/lcpu/src/LuaHelpers.hpp | 52 +++-- native/projects/lcpu/src/LuaShared.cpp | 38 ---- native/projects/lcpu/src/LuaShared.hpp | 56 ----- .../projects/lcpu/src/LuaSharedFunctions.inc | 128 ----------- native/projects/lcpu/src/main.cpp | 8 +- native/projects/riscv/include/riscv/Bus.hpp | 6 +- native/projects/riscv/src/Bus.cpp | 6 - native/projects/riscv/src/System.cpp | 8 +- test-gmod/main.c | 36 ++-- 16 files changed, 282 insertions(+), 383 deletions(-) delete mode 100644 native/projects/lcpu/src/LuaShared.cpp delete mode 100644 native/projects/lcpu/src/LuaShared.hpp delete mode 100644 native/projects/lcpu/src/LuaSharedFunctions.inc diff --git a/lua/autorun/lcpu_load.lua b/lua/autorun/lcpu_load.lua index 04dd5be..739a139 100644 --- a/lua/autorun/lcpu_load.lua +++ b/lua/autorun/lcpu_load.lua @@ -1,15 +1,59 @@ AddCSLuaFile() - -- prime the native lua module & add clientside files to send -- if running on the server if SERVER then require("lcpu_native") - - if LCPUNative.ModuleVersion != 1 then + if LCPUNative.ModuleVersion ~= 1 then print("Your LCPU native module is somehow lagging behind the Lua code. Please rebuild it.") LCPUNative = nil + return end + -- rapid iteration requires rapid solutions + --[[ + device = LCPUNative.CreateDevice(0x100000f0, 0x10) + device.a = 12 + device.apple = {} + + --print(device) + --print(device.a) + --print(device.apple) + +function device:Clock() + print("a") +end + +function device:Peek(address) + print("peek @ " .. address) + if address == 0x100000f0 then return 0x1010 end -- it a test! + + return 0x10000 +end + +function device:Poke(address, value) + if address == 0x100000f0 then + print("What you doing?") + end +end + +function device:Reset() + print("device was reset") +end + + cpu = LCPUNative.CreateCPU(64*1024) + + cpu:AttachDevice(device) + + print(device.Clock) + + print(cpu) + + -- unrolled test loops ftw + cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle(); + cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle(); + cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle(); + cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle(); +]] AddCSLuaFile("entities/gmod_lcpu_cpu.lua") end diff --git a/lua/entities/gmod_lcpu_cpu.lua b/lua/entities/gmod_lcpu_cpu.lua index 0783883..7407697 100644 --- a/lua/entities/gmod_lcpu_cpu.lua +++ b/lua/entities/gmod_lcpu_cpu.lua @@ -4,46 +4,51 @@ ENT.PrintName = "LCPU" ENT.Author = "Lily <3" -- no more, this deeply uses native APIs if CLIENT then return end - function ENT:Initialize() self:PhysicsInit(SOLID_VPHYSICS) self:SetMoveType(MOVETYPE_VPHYSICS) self:SetSolid(SOLID_VPHYSICS) -- 64 kb of ram for now. self.cpu = LCPUNative.CreateCPU(128 * 1024) - + print(self.cpu) + -- todo: cpu callbacks? once they become a thing -- test device framework - -- this is how I ideally want to do things, - -- dunno if it's possible - self.test_device = LCPUNative.CreateDevice() - print(self.test_device) - self.test_device:SetBase(0x12000000) - self.test_device:SetSize(0x10) - function self.test_device:Clock() - print("TestDevice Clock()") - end + -- (for once something works out how I wanted it to..) + self.test_device = LCPUNative.CreateDevice(0x11300000, 0x8) + self.test_device.register = 0x0 + --function self.test_device:Clock() + --print("TestDevice Clock()") + --end + function self.test_device:Peek(address) - if address == 0x12000000 then - -- it a test! - return CurTime() - end - return 0x10000 + --print("peek @ " .. address) + if address == self.Base then return CurTime() end -- it a test! + if address == self.Base + 4 then return self.register end + + return 0xffffffff end function self.test_device:Poke(address, value) - if address == 0x12000000 then - print("What you doing?") + print("poke of address " .. address .. " -> " .. value) + if address == self.Base + 4 then + print("LUAREG write") + self.register = value end end + function self.test_device:Reset() + print("device was reset") + -- clear the register + self.register = 0 + end + self.cpu:AttachDevice(self.test_device) end function ENT:Think() -- if not self.cpu:PoweredOn() then return end - self.cpu:Cycle() -- Even though this is gated by tickrate I'm just trying to be nice here self:NextThink(CurTime() + 0.1) diff --git a/native/projects/lcpu/CMakeLists.txt b/native/projects/lcpu/CMakeLists.txt index cafe513..746ec81 100644 --- a/native/projects/lcpu/CMakeLists.txt +++ b/native/projects/lcpu/CMakeLists.txt @@ -8,7 +8,6 @@ add_library(lcpu_native SHARED # Support code src/SourceSink.cpp - src/LuaShared.cpp ) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -22,6 +21,7 @@ endif() target_link_libraries(lcpu_native gmod_headers + lucore::lucore riscv::riscv ) diff --git a/native/projects/lcpu/src/LcpuGlobals.cpp b/native/projects/lcpu/src/LcpuGlobals.cpp index dccfe87..d91635f 100644 --- a/native/projects/lcpu/src/LcpuGlobals.cpp +++ b/native/projects/lcpu/src/LcpuGlobals.cpp @@ -1,9 +1,9 @@ #include "LcpuGlobals.hpp" +#include "GarrysMod/Lua/Interface.h" #include "LuaCpu.hpp" #include "LuaDevice.hpp" - - +#include "LuaHelpers.hpp" LUA_FUNCTION(LCPUNative_CreateCPU) { LUA->CheckType(1, GarrysMod::Lua::Type::Number); @@ -18,13 +18,16 @@ LUA_FUNCTION(LCPUNative_CreateCPU) { } LUA_FUNCTION(LCPUNative_CreateDevice) { - LuaDevice::Create(LUA); + auto base = LUA->CheckNumber(1); + auto size = LUA->CheckNumber(2); + lucore::LogInfo("Creating Lua device object mapped @ 0x{:08x} with size 0x{:08x}", static_cast(base), static_cast(size)); + LuaDevice::Create(LUA, static_cast(base), static_cast(size)); return 1; } void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA) { LuaCpu::Bind(LUA); - // LuaDevice::Bind(LUA); + LuaDevice::Bind(LUA); // clang-format off LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); diff --git a/native/projects/lcpu/src/LuaCpu.cpp b/native/projects/lcpu/src/LuaCpu.cpp index 3767ce1..cf2d4a2 100644 --- a/native/projects/lcpu/src/LuaCpu.cpp +++ b/native/projects/lcpu/src/LuaCpu.cpp @@ -75,13 +75,8 @@ LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, Reset) { LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, AttachDevice) { auto self = LUA_CLASS_GET(LuaCpu)(1); - auto device = LUA_CLASS_GET(LuaDevice)(1); + auto device = LUA_CLASS_GET(LuaDevice)(2); - // the bus is safe against this possibility, but - // I'd rather be doubly-safe tbh - if(!device) - LUA->ThrowError("Null device pointer"); - // Attach it LUA->PushBool(self->system->bus->AttachDevice(static_cast(device))); return 1; diff --git a/native/projects/lcpu/src/LuaDevice.cpp b/native/projects/lcpu/src/LuaDevice.cpp index e35e11d..8e21997 100644 --- a/native/projects/lcpu/src/LuaDevice.cpp +++ b/native/projects/lcpu/src/LuaDevice.cpp @@ -1,42 +1,23 @@ #include "LuaDevice.hpp" -#include "LuaHelpers.hpp" - LUA_CLASS_BIND_VARIABLES_IMPLEMENT(LuaDevice); -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaDevice, SetBase) { - auto self = LUA_CLASS_GET(LuaDevice)(1); - if(self->bus) - LUA->ThrowError("Do not call this on an attached device"); - self->base = static_cast(LUA->CheckNumber(2)); - return 0; -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaDevice, SetSize) { - auto self = LUA_CLASS_GET(LuaDevice)(1); - if(self->bus) - LUA->ThrowError("Do not call this on an attached device"); - self->size = static_cast(LUA->CheckNumber(2)); - return 0; -} - bool LuaDevice::Clocked() const { - // Even if Lua devices may not have a clock handler - // installed there's no real non-awful way to check, - // so just lie and say yes always. + // no real good rationale for checking here, + // since function calling does bail out properly return true; } void LuaDevice::Clock() { - LuaState->PushUserType(this, __lua_typeid); - LuaState->GetField(-2, "Clock"); - if(!LuaState->IsType(-1, GarrysMod::Lua::Type::Function)) { - LuaState->Pop(2); - return; - } - LuaState->Push(-2); // "self" - LuaState->Call(1, 0); - LuaState->Pop(); + LuaState->ReferencePush(tableReference); + LuaState->GetField(-1,"Clock"); + if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { + LuaState->Push(-2); // 'self' argument + LuaState->Call(1, 0); + } else { + LuaState->Pop(); // pop the Clock function off the stack + } + LuaState->Pop(); // pop the reference } riscv::Address LuaDevice::Base() const { @@ -48,60 +29,144 @@ riscv::Address LuaDevice::Size() const { } u32 LuaDevice::Peek(riscv::Address address) { - LuaState->PushUserType(this, __lua_typeid); - LuaState->GetField(-2, "Peek"); - if(!LuaState->IsType(-1, GarrysMod::Lua::Type::Function)) { - LuaState->Pop(2); - return -1; - } - LuaState->Push(-2); // "self" - LuaState->PushNumber(address); - LuaState->Call(2, 1); - auto result = LuaState->GetNumber(-1); - LuaState->Pop(); - return static_cast(result); + /*if(peekHandlerReference != -1) { + LuaState->ReferencePush(resetHandlerReference); + LuaState->PushNumber(static_cast(address)); + LuaState->Call(1, 1); + auto result = LuaState->GetNumber(-1); + LuaState->Pop(); + return static_cast(result); + }*/ + + LuaState->ReferencePush(tableReference); + LuaState->GetField(-1,"Peek"); + if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { + LuaState->Push(-2); // 'self' argument + LuaState->PushNumber(static_cast(address)); + LuaState->Call(2, 1); + + auto result = static_cast(LuaState->GetNumber(-1)); + LuaState->Pop(2); // pop result and the table off + return result; + } else { + LuaState->Pop(); // pop whatever Peek is off the stack + } + LuaState->Pop(); // pop the table reference + return 0xffffffff; } void LuaDevice::Poke(riscv::Address address, u32 value) { - LuaState->PushUserType(this, __lua_typeid); - LuaState->GetField(-2, "Poke"); - if(!LuaState->IsType(-1, GarrysMod::Lua::Type::Function)) { - LuaState->Pop(2); - return; - } - LuaState->Push(-2); // "self" - LuaState->PushNumber(address); - LuaState->PushNumber(value); - LuaState->Call(3, 0); - LuaState->Pop(); + /*if(pokeHandlerReference != -1) { + LuaState->ReferencePush(pokeHandlerReference); + LuaState->PushNumber(address); + LuaState->PushNumber(value); + LuaState->Call(2, 0); + }*/ + + LuaState->ReferencePush(tableReference); + LuaState->GetField(-1,"Poke"); + if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { + LuaState->Push(-2); // 'self' argument + LuaState->PushNumber(static_cast(address)); + LuaState->PushNumber(static_cast(value)); + LuaState->Call(3, 0); + } else { + LuaState->Pop(); // pop whatever Peek is + } + LuaState->Pop(); // pop the table reference } void LuaDevice::Reset() { - LuaState->PushUserType(this, __lua_typeid); - LuaState->GetField(-2, "Reset"); - if(!LuaState->IsType(-1, GarrysMod::Lua::Type::Function)) - return; + /*if(resetHandlerReference != -1) { + LuaState->ReferencePush(resetHandlerReference); + LuaState->Call(0, 0); + }*/ - LuaState->Push(-2); // "self" - LuaState->Call(1, 0); - LuaState->Pop(); + LuaState->ReferencePush(tableReference); + LuaState->GetField(-1,"Reset"); + if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { + LuaState->Push(-2); // 'self' argument + LuaState->Call(1, 0); + } else { + LuaState->Pop(); // pop whatever reset is + } + LuaState->Pop(); // pop the reference } -LuaDevice::~LuaDevice() = default; +LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) { +} + +LuaDevice::~LuaDevice() { + // Free all refererences + if(tableReference == -1) + LuaState->ReferenceFree(tableReference); +} + +LUA_MEMBER_FUNCTION_IMPLEMENT(LuaDevice, __index) { + auto self = LUA_CLASS_GET(LuaDevice)(1); + //lucore::LogInfo("metamethod __index call"); + + // TODO: before moving this to a shared lua object class thing + // and moving the CPU class to use this way of doing things + // I should probably try and like, add stuff to ensure native + // methods can be registered as well,, + LUA->ReferencePush(self->tableReference); + LUA->Push(2); + LUA->GetTable(-2); + return 1; // the value +} + +LUA_MEMBER_FUNCTION_IMPLEMENT(LuaDevice, __newindex) { + auto self = LUA_CLASS_GET(LuaDevice)(1); + //lucore::LogInfo("metamethod __newindex call"); + + // Always push onto the table. + // TODO: This function + // should error on attempt to __newindex any native methods + // (when moved to a shared place) + LUA->ReferencePush(self->tableReference); + LUA->Push(2); + LUA->Push(3); + LUA->SetTable(-3); + LUA->Pop(); + return 0; +} void LuaDevice::Bind(GarrysMod::Lua::ILuaBase* LUA) { // clang-format off - // TODO: I need to figure out how to like, set up metamethod stuff - // so it all properly works. - LUA_CLASS_BIND_BEGIN(LuaDevice); - LUA_SET_C_FUNCTION(SetBase) - LUA_SET_C_FUNCTION(SetSize) + //LUA_CLASS_BIND_BEGIN(LuaDevice) + __lua_typeid = LUA->CreateMetaTable("LuaDevice"); + LUA->PushSpecial(GarrysMod::Lua::SPECIAL_REG); + LUA->PushNumber(__lua_typeid); + LUA->SetField(-2, "LuaDevice__typeid"); + LUA->Pop(); /* pop registry */ + + LUA_SET_C_FUNCTION(__gc) + LUA_SET_C_FUNCTION(__index) + LUA_SET_C_FUNCTION(__newindex) LUA_CLASS_BIND_END(); // clang-format on + + } -void LuaDevice::Create(GarrysMod::Lua::ILuaBase* LUA) { - auto device = new LuaDevice(); +void LuaDevice::Create(GarrysMod::Lua::ILuaBase* LUA, riscv::Address base, riscv::Address size) { + auto device = new LuaDevice(base, size); device->LuaState = LUA; + + LUA->CreateTable(); + device->tableReference = LUA->ReferenceCreate(); + LUA->Pop(); + + // push base/size properties for lua to have a looksee at ! + // ideally these should be handled as metamethods in __index, + // but i don't quite feel like making gmod sol2 yet /shrug + LUA->ReferencePush(device->tableReference); + LUA->PushNumber(static_cast(base)); + LUA->SetField(-2, "Base"); + LUA->PushNumber(static_cast(base)); + LUA->SetField(-2, "Size"); + LUA->Pop(); + LUA->PushUserType(device, __lua_typeid); } diff --git a/native/projects/lcpu/src/LuaDevice.hpp b/native/projects/lcpu/src/LuaDevice.hpp index 19ecc18..4b8dd98 100644 --- a/native/projects/lcpu/src/LuaDevice.hpp +++ b/native/projects/lcpu/src/LuaDevice.hpp @@ -8,7 +8,7 @@ struct LuaDevice : public riscv::Bus::MmioDevice { /// Lua binding stuff static void Bind(GarrysMod::Lua::ILuaBase* LUA); - static void Create(GarrysMod::Lua::ILuaBase* LUA); + static void Create(GarrysMod::Lua::ILuaBase* LUA, riscv::Address base, riscv::Address size); ~LuaDevice(); @@ -26,14 +26,15 @@ struct LuaDevice : public riscv::Bus::MmioDevice { // class binding stuff LUA_CLASS_BIND_VARIABLES(private); - // Do not call these once attached to a bus. - LUA_MEMBER_FUNCTION(SetBase); - LUA_MEMBER_FUNCTION(SetSize); + LUA_MEMBER_FUNCTION(__index); + LUA_MEMBER_FUNCTION(__newindex); - // GetBase/GetSize? + LuaDevice(riscv::Address base, riscv::Address size); riscv::Address base {}; riscv::Address size {}; - GarrysMod::Lua::ILuaBase* LuaState; + + // this should be a common type tbh + int tableReference = -1; }; diff --git a/native/projects/lcpu/src/LuaHelpers.hpp b/native/projects/lcpu/src/LuaHelpers.hpp index f818f2e..20b88ed 100644 --- a/native/projects/lcpu/src/LuaHelpers.hpp +++ b/native/projects/lcpu/src/LuaHelpers.hpp @@ -34,31 +34,32 @@ public: \ static int __lua_typeid; \ ACCESS_LEVEL: \ - LUA_MEMBER_FUNCTION(__gc); + LUA_MEMBER_FUNCTION(__gc); // Implement required binding variables (typically in a .cpp file). -#define LUA_CLASS_BIND_VARIABLES_IMPLEMENT(T) \ - int T::__lua_typeid = 0; \ - LUA_MEMBER_FUNCTION_IMPLEMENT(T, __gc) { \ - LUA->CheckType(1, T::__lua_typeid); \ - auto self = LUA->GetUserType(1, T::__lua_typeid); \ - if(self != nullptr) { /* GetUserType returns nullptr on failure */ \ - lucore::LogInfo("GCing {} object", #T); \ - delete self; \ - } \ - return 0; \ - } +#define LUA_CLASS_BIND_VARIABLES_IMPLEMENT(T) \ + int T::__lua_typeid = 0; \ + LUA_MEMBER_FUNCTION_IMPLEMENT(T, __gc) { \ + LUA->CheckType(1, T::__lua_typeid); \ + auto self = LUA->GetUserType(1, T::__lua_typeid); \ + if(self != nullptr) { /* GetUserType returns nullptr on failure */ \ + lucore::LogInfo("GCing {} object @ {:p}", #T, static_cast(self)); \ + delete self; \ + } \ + return 0; \ + } + // Begin the Bind() method of a class. This just sets up boilerplate // and required things to setup a class. -#define LUA_CLASS_BIND_BEGIN(T) \ - T::__lua_typeid = LUA->CreateMetaTable(#T); \ - LUA->PushSpecial(GarrysMod::Lua::SPECIAL_REG); \ - LUA->PushNumber(T::__lua_typeid); \ - LUA->SetField(-2, #T "__typeid"); \ - LUA->Pop(); /* pop registry */ \ - LUA->Push(-1); \ - LUA->SetField(-2, "__index"); \ +#define LUA_CLASS_BIND_BEGIN(T) \ + T::__lua_typeid = LUA->CreateMetaTable(#T); \ + LUA->PushSpecial(GarrysMod::Lua::SPECIAL_REG); \ + LUA->PushNumber(T::__lua_typeid); \ + LUA->SetField(-2, #T "__typeid"); \ + LUA->Pop(); /* pop registry */ \ + LUA->Push(-1); \ + LUA->SetField(-2, "__index"); \ LUA_SET_C_FUNCTION(__gc) // End the Bind() method. @@ -73,3 +74,14 @@ #define LUA_SET_C_FUNCTION_NAME(name, altName) \ LUA->PushCFunction(name); \ LUA->SetField(-2, altName); + + +inline std::string GetLuaString(GarrysMod::Lua::ILuaBase* LUA, int stackPos) { + unsigned len{}; + auto ptr = LUA->GetString(stackPos, &len); + if(ptr) { + return std::string(ptr, len); + } else { + return {}; + } +} diff --git a/native/projects/lcpu/src/LuaShared.cpp b/native/projects/lcpu/src/LuaShared.cpp deleted file mode 100644 index 032269b..0000000 --- a/native/projects/lcpu/src/LuaShared.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "LuaShared.hpp" - -#include -#include - -namespace lcpu::lua { - - // A global pointer to the loaded instance of the lua_shared library. - lucore::Library* luaSharedLibrary = nullptr; - -#define LUA_SHARED_FUNC(Retty, name, ...) Retty (*name)(__VA_ARGS__) = nullptr; -#include "LuaSharedFunctions.inc" -#undef LUA_SHARED_FUNC - - void LoadLuaShared() { - // Open the lua_shared library - luaSharedLibrary = lucore::Library::OpenExisting("lua_shared"); - LUCORE_CHECK(luaSharedLibrary != nullptr, "Could not open lua_shared library for some reason."); - - // Load the functions from lua_shared - // This is helped quite a bit by using an x-macro -#define LUA_SHARED_FUNC(Retty, name, ...) \ - name = luaSharedLibrary->Symbol(#name); \ - LUCORE_CHECK(name != nullptr, "Could not load lua_shared function \"{}\"", #name); -#include "LuaSharedFunctions.inc" -#undef LUA_SHARED_FUNC - } - - void UnloadLuaShared() { - LUCORE_ASSERT(luaSharedLibrary != nullptr, "UnloadLuaShared() should only be called if LoadLuaShared() was called"); - delete luaSharedLibrary; - -#define LUA_SHARED_FUNC(Retty, name, ...) name = nullptr; -#include "LuaSharedFunctions.inc" -#undef LUA_SHARED_FUNC - } - -} // namespace lcpu::lua diff --git a/native/projects/lcpu/src/LuaShared.hpp b/native/projects/lcpu/src/LuaShared.hpp deleted file mode 100644 index 168ab0e..0000000 --- a/native/projects/lcpu/src/LuaShared.hpp +++ /dev/null @@ -1,56 +0,0 @@ -//! Loader/types for lua_shared API. I plan to use this instead of the Garry's Mod -//! ILuaBase interface; they are interchangable (and in fact, less friction to use!) - -#pragma once - -#include - -namespace lcpu::lua { - -#define LUA_IDSIZE 60 /* Size of lua_Debug.short_src. */ - - struct lua_Debug { - int event; - const char* name; /* (n) */ - const char* namewhat; /* (n) `global', `local', `field', `method' */ - const char* what; /* (S) `Lua', `C', `main', `tail' */ - const char* source; /* (S) */ - int currentline; /* (l) */ - int nups; /* (u) number of upvalues */ - int linedefined; /* (S) */ - int lastlinedefined; /* (S) */ - char short_src[LUA_IDSIZE]; /* (S) */ - /* private part */ - int i_ci; /* active function */ - }; - - typedef int (*lua_CFunction)(lua_State* L); - typedef void* (*lua_Alloc)(void* ud, void* ptr, size_t osize, size_t nsize); - typedef const char* (*lua_Reader)(lua_State* L, void* ud, size_t* sz); - typedef int (*lua_Writer)(lua_State* L, const void* p, size_t sz, void* ud); - //typedef struct lua_Debug lua_Debug; /* activation record */ - typedef void (*lua_Hook)(lua_State* L, lua_Debug* ar); - - typedef struct luaL_Buffer { - char* p; /* current position in buffer */ - int lvl; /* number of strings in the stack (level) */ - lua_State* L; - char buffer[8192]; - } luaL_Buffer; - - typedef struct luaL_Reg { - const char* name; - lua_CFunction func; - } luaL_Reg; - -#define LUA_SHARED_FUNC(Retty, name, ...) extern Retty (*name)(__VA_ARGS__); - #include "LuaSharedFunctions.inc" -#undef LUA_SHARED_FUNC - - /// Load lua_shared - void LoadLuaShared(); - - /// .. and unload it. - void UnloadLuaShared(); - -} // namespace lcpu::lua diff --git a/native/projects/lcpu/src/LuaSharedFunctions.inc b/native/projects/lcpu/src/LuaSharedFunctions.inc deleted file mode 100644 index f749d9d..0000000 --- a/native/projects/lcpu/src/LuaSharedFunctions.inc +++ /dev/null @@ -1,128 +0,0 @@ -//! This is an X-Macro file of all the interesting functions in lua_shared -LUA_SHARED_FUNC(lua_State*, luaL_newstate, void); -LUA_SHARED_FUNC(int, luaL_loadstring, lua_State *L, const char* code); -LUA_SHARED_FUNC(lua_CFunction, lua_atpanic, lua_State *L, lua_CFunction panicf); -LUA_SHARED_FUNC(void, lua_call, lua_State *L, int nargs, int nresults); -LUA_SHARED_FUNC(int, lua_checkstack, lua_State *L, int size); -LUA_SHARED_FUNC(void, lua_close, lua_State *L); -LUA_SHARED_FUNC(void, lua_concat, lua_State*L,int n); -LUA_SHARED_FUNC(int, lua_cpcall, lua_State *L, lua_CFunction func, void *ud); -LUA_SHARED_FUNC(void, lua_createtable, lua_State *L, int narray, int nrec); -LUA_SHARED_FUNC(int, lua_dump, lua_State *L, lua_Writer writer, void *data); -LUA_SHARED_FUNC(int, lua_equal, lua_State *L, int idx1, int idx2); -LUA_SHARED_FUNC(int, lua_error, lua_State *L); -LUA_SHARED_FUNC(int, lua_gc, lua_State *L, int what, int data); -LUA_SHARED_FUNC(lua_Alloc, lua_getallocf, lua_State *L, void **ud); -LUA_SHARED_FUNC(void, lua_getfenv, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_getfield, lua_State *L, int idx, const char *k); -LUA_SHARED_FUNC(lua_Hook, lua_gethook, lua_State *L); -LUA_SHARED_FUNC(int, lua_gethookcount, lua_State *L); -LUA_SHARED_FUNC(int, lua_gethookmask, lua_State *L); -LUA_SHARED_FUNC(int, lua_getinfo, lua_State *L, const char *what, lua_Debug *ar); -LUA_SHARED_FUNC(const char*, lua_getlocal, lua_State *L, const lua_Debug *ar, int n); -LUA_SHARED_FUNC(int, lua_getmetatable, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_getstack, lua_State *L, int level, lua_Debug *ar); -LUA_SHARED_FUNC(void, lua_gettable, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_gettop, lua_State *L); -LUA_SHARED_FUNC(const char*, lua_getupvalue, lua_State *L, int idx, int n); -LUA_SHARED_FUNC(void, lua_insert, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_iscfunction, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_isnumber, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_isstring, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_isuserdata, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_lessthan, lua_State *L, int idx1, int idx2); -LUA_SHARED_FUNC(int, lua_load, lua_State *L, lua_Reader reader, void *dt, const char *chunkname); -LUA_SHARED_FUNC(int, lua_loadx, lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); -LUA_SHARED_FUNC(lua_State*, lua_newstate, lua_Alloc f, void *ud); -LUA_SHARED_FUNC(lua_State*, lua_newthread, lua_State *L); -LUA_SHARED_FUNC(void*, lua_newuserdata, lua_State *L, size_t size); -LUA_SHARED_FUNC(int, lua_next, lua_State *L, int idx); -LUA_SHARED_FUNC(size_t, lua_objlen, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_pcall, lua_State *L, int nargs, int nresults, int errfunc); -LUA_SHARED_FUNC(void, lua_pushboolean, lua_State *L, int b); -LUA_SHARED_FUNC(void, lua_pushcclosure, lua_State *L, lua_CFunction f, int n); -LUA_SHARED_FUNC(const char*, lua_pushfstring, lua_State *L, const char *fmt, ...); -LUA_SHARED_FUNC(void, lua_pushlightuserdata, lua_State *L, void *p); -LUA_SHARED_FUNC(void, lua_pushlstring, lua_State *L, const char *str, size_t len); -LUA_SHARED_FUNC(void, lua_pushnil, lua_State *L); -LUA_SHARED_FUNC(void, lua_pushnumber, lua_State *L, double n); -LUA_SHARED_FUNC(void, lua_pushstring, lua_State *L, const char *str); -LUA_SHARED_FUNC(int, lua_pushthread, lua_State *L); -LUA_SHARED_FUNC(void, lua_pushvalue, lua_State *L, int idx); -LUA_SHARED_FUNC(const char*, lua_pushvfstring, lua_State *L, const char *fmt, char* argp); -LUA_SHARED_FUNC(int, lua_rawequal, lua_State *L, int idx1, int idx2); -LUA_SHARED_FUNC(void, lua_rawget, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_rawgeti, lua_State *L, int idx, int n); -LUA_SHARED_FUNC(void, lua_rawset, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_rawseti, lua_State *L, int idx, int n); -LUA_SHARED_FUNC(void, lua_remove, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_replace, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_setallocf, lua_State *L, lua_Alloc f, void *ud); -LUA_SHARED_FUNC(int, lua_setfenv, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_setfield, lua_State *L, int idx, const char *k); -LUA_SHARED_FUNC(int, lua_sethook, lua_State *L, lua_Hook func, int mask, int count); -LUA_SHARED_FUNC(const char *, lua_setlocal, lua_State *L, const lua_Debug *ar, int n); -LUA_SHARED_FUNC(int, lua_setmetatable, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_settable, lua_State *L, int idx); -LUA_SHARED_FUNC(void, lua_settop, lua_State *L, int idx); -LUA_SHARED_FUNC(const char*, lua_setupvalue, lua_State *L, int idx, int n); -LUA_SHARED_FUNC(int, lua_status, lua_State *L); -LUA_SHARED_FUNC(int, lua_toboolean, lua_State *L, int idx); -LUA_SHARED_FUNC(lua_CFunction, lua_tocfunction, lua_State *L, int idx); -LUA_SHARED_FUNC(const char*, lua_tolstring, lua_State *L, int idx, size_t *len); -LUA_SHARED_FUNC(double, lua_tonumber, lua_State *L, int idx); -LUA_SHARED_FUNC(const void*, lua_topointer, lua_State *L, int idx); -LUA_SHARED_FUNC(lua_State*, lua_tothread, lua_State *L, int idx); -LUA_SHARED_FUNC(void*, lua_touserdata, lua_State *L, int idx); -LUA_SHARED_FUNC(int, lua_type, lua_State *L, int idx); -LUA_SHARED_FUNC(const char*, lua_typename, lua_State *L, int t); -LUA_SHARED_FUNC(void*, lua_upvalueid, lua_State *L, int idx, int n); -LUA_SHARED_FUNC(void, lua_upvaluejoin, lua_State *L, int idx1, int n1, int idx2, int n2); -LUA_SHARED_FUNC(void, lua_xmove, lua_State *from, lua_State *to, int n); -LUA_SHARED_FUNC(int, lua_yield, lua_State *L, int nresults); -LUA_SHARED_FUNC(int, luaJIT_setmode, lua_State *L, int idx, int mode); -LUA_SHARED_FUNC(void, luaL_addlstring, luaL_Buffer *B, const char *s, size_t l); -LUA_SHARED_FUNC(void, luaL_addstring, luaL_Buffer *B, const char *s); -LUA_SHARED_FUNC(void, luaL_addvalue, luaL_Buffer *B); -LUA_SHARED_FUNC(int, luaL_argerror, lua_State *L, int narg, const char *msg); -LUA_SHARED_FUNC(void, luaL_buffinit, lua_State *L, luaL_Buffer *B); -LUA_SHARED_FUNC(int, luaL_callmeta, lua_State *L, int idx, const char *field); -LUA_SHARED_FUNC(void, luaL_checkany, lua_State *L, int idx); -LUA_SHARED_FUNC(const char*, luaL_checklstring, lua_State *L, int idx, size_t *len); -LUA_SHARED_FUNC(double, luaL_checknumber, lua_State *L, int idx); -LUA_SHARED_FUNC(int, luaL_checkoption, lua_State *L, int idx, const char *def, const char *const lst[]); -LUA_SHARED_FUNC(void, luaL_checkstack, lua_State *L, int size, const char *msg); -LUA_SHARED_FUNC(void, luaL_checktype, lua_State *L, int idx, int tt); -LUA_SHARED_FUNC(void*, luaL_checkudata, lua_State *L, int idx, const char *tname); -LUA_SHARED_FUNC(int, luaL_error, lua_State *L, const char *fmt, ...); -LUA_SHARED_FUNC(int, luaL_execresult, lua_State *L, int stat); -LUA_SHARED_FUNC(int, luaL_fileresult, lua_State *L, int stat, const char *fname); -LUA_SHARED_FUNC(const char*, luaL_findtable, lua_State *L, int idx, const char *fname, int szhint); -LUA_SHARED_FUNC(int, luaL_getmetafield, lua_State *L, int idx, const char *field); -LUA_SHARED_FUNC(const char*, luaL_gsub, lua_State *L, const char *s, const char *p, const char *r); -LUA_SHARED_FUNC(int, luaL_loadbuffer, lua_State *L, const char *buff, size_t sz, const char *name); -LUA_SHARED_FUNC(int, luaL_loadbufferx, lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); -LUA_SHARED_FUNC(int, luaL_loadfile, lua_State *L, const char *filename); -LUA_SHARED_FUNC(int, luaL_loadfilex, lua_State *L, const char *filename, const char *mode); -LUA_SHARED_FUNC(int, luaL_newmetatable, lua_State *L, const char *tname); -LUA_SHARED_FUNC(void, luaL_openlib, lua_State *L, const char *libname, const luaL_Reg *l, int nup); -LUA_SHARED_FUNC(int, luaL_openlibs, lua_State *L); -LUA_SHARED_FUNC(const char*, luaL_optlstring, lua_State *L, int idx, const char *def, size_t *len); -LUA_SHARED_FUNC(double, luaL_optnumber, lua_State *L, int idx, double def); -LUA_SHARED_FUNC(char*, luaL_prepbuffer, luaL_Buffer *B); -LUA_SHARED_FUNC(void, luaL_pushresult, luaL_Buffer *B); -LUA_SHARED_FUNC(int, luaL_ref, lua_State *L, int t); -LUA_SHARED_FUNC(void, luaL_register, lua_State *L, const char *libname, const luaL_Reg *l); -LUA_SHARED_FUNC(void, luaL_traceback, lua_State *L, lua_State *L1, const char *msg, int level); -LUA_SHARED_FUNC(int, luaL_typerror, lua_State *L, int narg, const char *tname); -LUA_SHARED_FUNC(void, luaL_unref, lua_State *L, int t, int ref); -LUA_SHARED_FUNC(void, luaL_where, lua_State *L, int lvl); -LUA_SHARED_FUNC(int, luaopen_base, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_bit, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_debug, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_jit, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_math, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_os, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_package, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_string, lua_State *L); -LUA_SHARED_FUNC(int, luaopen_table, lua_State *L); diff --git a/native/projects/lcpu/src/main.cpp b/native/projects/lcpu/src/main.cpp index 101e20b..3ee4596 100644 --- a/native/projects/lcpu/src/main.cpp +++ b/native/projects/lcpu/src/main.cpp @@ -6,19 +6,15 @@ #include "LcpuGlobals.hpp" -#include "LuaShared.hpp" - GMOD_MODULE_OPEN() { + // Initialize our lua_shared binding. It is important we ca lucore::Logger::The().AttachSink(lcpu::SourceSink::The()); lucore::LogInfo("LCPU Native Module! (ModuleVersion {})", LCPU_MODULE_VERSION); - lcpu::lua::LoadLuaShared(); - GlobalsBind(LUA); return 0; } -GMOD_MODULE_CLOSE() { - lcpu::lua::UnloadLuaShared(); +GMOD_MODULE_CLOSE() { return 0; } diff --git a/native/projects/riscv/include/riscv/Bus.hpp b/native/projects/riscv/include/riscv/Bus.hpp index cea373f..5d1491e 100644 --- a/native/projects/riscv/include/riscv/Bus.hpp +++ b/native/projects/riscv/include/riscv/Bus.hpp @@ -105,14 +105,10 @@ namespace riscv { virtual void Poke(Address address, u32 value) = 0; }; - /// Bus destructor. - /// This frees the memory for all devices. - ~Bus(); - /// Attach a device to the bus. /// /// Note that once this function is called (and the device is successfully added), - /// the object pointed to by [device] is owned by the Bus object, and should not be deleted. + /// the object pointed to by [device] should last at least as long as the bus. /// /// # Returns /// This function returns true if the device was able to be put on the bus. diff --git a/native/projects/riscv/src/Bus.cpp b/native/projects/riscv/src/Bus.cpp index 5459ba5..819cfa9 100644 --- a/native/projects/riscv/src/Bus.cpp +++ b/native/projects/riscv/src/Bus.cpp @@ -4,12 +4,6 @@ namespace riscv { - Bus::~Bus() { - // Free all devices - for(auto device : devices) - delete device; - } - bool Bus::AttachDevice(Device* device) { if(!device) return false; diff --git a/native/projects/riscv/src/System.cpp b/native/projects/riscv/src/System.cpp index caaa94e..e9e1d31 100644 --- a/native/projects/riscv/src/System.cpp +++ b/native/projects/riscv/src/System.cpp @@ -30,7 +30,13 @@ namespace riscv { System::~System() { delete cpu; - delete bus; // the rest of the device pointers will be deleted by the bus. + delete bus; + + // delete our devices + // externally bound devices should clean themselves up + delete clnt; + delete syscon; + delete ram; } void System::Step() { diff --git a/test-gmod/main.c b/test-gmod/main.c index 0b4fbc2..a03fb08 100644 --- a/test-gmod/main.c +++ b/test-gmod/main.c @@ -1,7 +1,7 @@ // a simple test program - this version would talk to a device // written in GLua -#include #include +#include uint32_t strlen(const char* str) { if(!str) @@ -12,7 +12,9 @@ uint32_t strlen(const char* str) { return c - str; } -#define GLUA_DEVICE *(volatile uint32_t*)0x12000000 +#define GLUA_DEVICE_BASE 0x11300000 // base address of the lua test device +#define GLUA_DEVICE_WORLDTIME *(volatile uint32_t*)GLUA_DEVICE_BASE // world time register (read only) +#define GLUA_DEVICE_LUAREG *(volatile uint32_t*)(GLUA_DEVICE_BASE + 4) // lua register (read/write) #define SYSCON *(volatile uint32_t*)0x11100000 @@ -70,9 +72,9 @@ void vprintf(const char* format, va_list val) { for(int i = 0; i < fl; ++i) { switch(format[i]) { case '%': - if(format[i+1] == '%') + if(format[i + 1] == '%') putc('%'); - switch(format[i+1]) { + switch(format[i + 1]) { case 'i': case 'd': { char a[32]; @@ -81,6 +83,7 @@ void vprintf(const char* format, va_list val) { const int al = strlen(a); for(int j = 0; j < al; ++j) putc(a[j]); + i++; } break; case 's': { @@ -89,16 +92,13 @@ void vprintf(const char* format, va_list val) { puts("(null)"); else puts(p); + i++; }; - default: - putc(' '); - break; + default: putc(' '); break; } - break; - default: - putc(format[i]); - break; + break; + default: putc(format[i]); break; } } } @@ -106,17 +106,21 @@ void vprintf(const char* format, va_list val) { void printf(const char* format, ...) { va_list val; va_start(val, format); - vprintf(format, val); + vprintf(format, val); va_end(val); } - - void main() { puts("fuck you garry I win"); - for(int i = 0; i < 256; ++i) - printf("uhh %d\n", GLUA_DEVICE); + for(int i = 0; i < 8; ++i) + printf("GLUA_DEVICE_WORLDTIME reading says -> %d\n", GLUA_DEVICE_WORLDTIME); + + // try writing to it + GLUA_DEVICE_LUAREG = 0x1234; + + for(int i = 0; i < 8; ++i) + printf("GLUA_DEVICE_LUAREG reading says -> %d\n", GLUA_DEVICE_LUAREG); SYSCON = 0x5555; }