From ee558472202531abeadfc0e11d8ede3ea4dfff78 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 26 May 2014 01:57:10 +0200 Subject: [PATCH] Improved LuaInstance class Better handling of panic (showing the actual error) Secured arrays with static assert Added ArgCheck Added ArgError Added reference handling Improved DumpStack method (Now printing the address of functions, tables, threads) Former-commit-id: 5ae9a1aefca4b8c50aa57db99da3b778cb1ebff4 --- include/Nazara/Lua/LuaInstance.hpp | 10 +++++ src/Nazara/Lua/LuaInstance.cpp | 64 +++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index f36ee1ae5..a7d530c6a 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -30,6 +30,11 @@ class NAZARA_API NzLuaInstance : NzNonCopyable NzLuaInstance(); ~NzLuaInstance(); + void ArgCheck(bool condition, unsigned int argNum, const char* error); + void ArgCheck(bool condition, unsigned int argNum, const NzString& error); + int ArgError(unsigned int argNum, const char* error); + int ArgError(unsigned int argNum, const NzString& error); + void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; @@ -52,6 +57,9 @@ class NAZARA_API NzLuaInstance : NzNonCopyable void Concatenate(int count); + int CreateReference(); + void DestroyReference(int ref); + NzString DumpStack() const; void Error(const char* message); @@ -106,6 +114,7 @@ class NAZARA_API NzLuaInstance : NzNonCopyable void PushMetatable(const NzString& str); void PushNil(); void PushNumber(double value); + void PushReference(int ref); void PushString(const char* str); void PushString(const NzString& str); void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0); @@ -130,6 +139,7 @@ class NAZARA_API NzLuaInstance : NzNonCopyable bool ToBoolean(int index) const; int ToInteger(int index, bool* succeeded = nullptr) const; double ToNumber(int index, bool* succeeded = nullptr) const; + const void* ToPointer(int index) const; const char* ToString(int index, std::size_t* length = nullptr) const; unsigned int ToUnsigned(int index, bool* succeeded = nullptr) const; void* ToUserdata(int index) const; diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index 23c3ab9fe..e3fa382e5 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -28,9 +28,9 @@ namespace int AtPanic(lua_State* state) { - NazaraUnused(state); + NzString lastError(lua_tostring(state, -1)); - throw std::runtime_error("Lua panic !"); + throw std::runtime_error("Lua panic: " + lastError); } const char* StreamReader(lua_State* state, void* data, std::size_t* size) @@ -48,13 +48,15 @@ namespace } } - int s_comparisons[nzLuaComparison_Max+1] = { + int s_comparisons[] = { LUA_OPEQ, // nzLuaComparison_Equality LUA_OPLT, // nzLuaComparison_Less LUA_OPLE // nzLuaComparison_LessOrEqual }; - int s_operations[nzLuaOperation_Max+1] = { + static_assert(sizeof(s_comparisons)/sizeof(int) == nzLuaComparison_Max+1, "Lua comparison array is incomplete"); + + int s_operations[] = { LUA_OPADD, // nzLuaOperation_Addition LUA_OPDIV, // nzLuaOperation_Division LUA_OPPOW, // nzLuaOperation_Exponentiation @@ -64,7 +66,9 @@ namespace LUA_OPSUB // nzLuaOperation_Substraction }; - int s_types[nzLuaType_Max+1] = { + static_assert(sizeof(s_operations)/sizeof(int) == nzLuaOperation_Max+1, "Lua operation array is incomplete"); + + int s_types[] = { LUA_TBOOLEAN, // nzLuaType_Boolean LUA_TFUNCTION, // nzLuaType_Function LUA_TLIGHTUSERDATA, // nzLuaType_LightUserdata @@ -76,6 +80,8 @@ namespace LUA_TTHREAD, // nzLuaType_Thread LUA_TUSERDATA // nzLuaType_Userdata }; + + static_assert(sizeof(s_types)/sizeof(int) == nzLuaType_Max+1, "Lua type array is incomplete"); } NzLuaInstance::NzLuaInstance() : @@ -95,6 +101,26 @@ NzLuaInstance::~NzLuaInstance() lua_close(m_state); } +void NzLuaInstance::ArgCheck(bool condition, unsigned int argNum, const char* error) +{ + luaL_argcheck(m_state, condition, argNum, error); +} + +void NzLuaInstance::ArgCheck(bool condition, unsigned int argNum, const NzString& error) +{ + luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer()); +} + +int NzLuaInstance::ArgError(unsigned int argNum, const char* error) +{ + return luaL_argerror(m_state, argNum, error); +} + +int NzLuaInstance::ArgError(unsigned int argNum, const NzString& error) +{ + return luaL_argerror(m_state, argNum, error.GetConstBuffer()); +} + void NzLuaInstance::CheckAny(int index) const { luaL_checkany(m_state, index); @@ -224,6 +250,16 @@ void NzLuaInstance::Concatenate(int count) lua_concat(m_state, count); } +int NzLuaInstance::CreateReference() +{ + return luaL_ref(m_state, LUA_REGISTRYINDEX); +} + +void NzLuaInstance::DestroyReference(int ref) +{ + luaL_unref(m_state, LUA_REGISTRYINDEX, ref); +} + NzString NzLuaInstance::DumpStack() const { NzStringStream stream; @@ -240,7 +276,7 @@ NzString NzLuaInstance::DumpStack() const break; case nzLuaType_Function: - stream << "Function"; + stream << "Function(" << ToPointer(i) << ')'; break; case nzLuaType_LightUserdata: @@ -265,15 +301,15 @@ NzString NzLuaInstance::DumpStack() const break; case nzLuaType_Table: - stream << "Table"; + stream << "Table(" << ToPointer(i) << ')'; break; case nzLuaType_Thread: - stream << "Thread"; + stream << "Thread(" << ToPointer(i) << ')'; break; default: - stream << "Unknown"; + stream << "Unknown(" << ToPointer(i) << ')'; break; } @@ -620,6 +656,11 @@ void NzLuaInstance::PushNumber(double value) lua_pushnumber(m_state, value); } +void NzLuaInstance::PushReference(int ref) +{ + lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref); +} + void NzLuaInstance::PushString(const char* str) { lua_pushstring(m_state, str); @@ -745,6 +786,11 @@ double NzLuaInstance::ToNumber(int index, bool* succeeded) const return result; } +const void* NzLuaInstance::ToPointer(int index) const +{ + return lua_topointer(m_state, index); +} + const char* NzLuaInstance::ToString(int index, std::size_t* length) const { return lua_tolstring(m_state, index, length);