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
This commit is contained in:
Lynix 2014-05-26 01:57:10 +02:00
parent b899ff294b
commit ee55847220
2 changed files with 65 additions and 9 deletions

View File

@ -30,6 +30,11 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
NzLuaInstance(); NzLuaInstance();
~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; void CheckAny(int index) const;
bool CheckBoolean(int index) const; bool CheckBoolean(int index) const;
bool CheckBoolean(int index, bool defValue) const; bool CheckBoolean(int index, bool defValue) const;
@ -52,6 +57,9 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
void Concatenate(int count); void Concatenate(int count);
int CreateReference();
void DestroyReference(int ref);
NzString DumpStack() const; NzString DumpStack() const;
void Error(const char* message); void Error(const char* message);
@ -106,6 +114,7 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
void PushMetatable(const NzString& str); void PushMetatable(const NzString& str);
void PushNil(); void PushNil();
void PushNumber(double value); void PushNumber(double value);
void PushReference(int ref);
void PushString(const char* str); void PushString(const char* str);
void PushString(const NzString& str); void PushString(const NzString& str);
void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0); void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0);
@ -130,6 +139,7 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
bool ToBoolean(int index) const; bool ToBoolean(int index) const;
int ToInteger(int index, bool* succeeded = nullptr) const; int ToInteger(int index, bool* succeeded = nullptr) const;
double ToNumber(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; const char* ToString(int index, std::size_t* length = nullptr) const;
unsigned int ToUnsigned(int index, bool* succeeded = nullptr) const; unsigned int ToUnsigned(int index, bool* succeeded = nullptr) const;
void* ToUserdata(int index) const; void* ToUserdata(int index) const;

View File

@ -28,9 +28,9 @@ namespace
int AtPanic(lua_State* state) 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) 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_OPEQ, // nzLuaComparison_Equality
LUA_OPLT, // nzLuaComparison_Less LUA_OPLT, // nzLuaComparison_Less
LUA_OPLE // nzLuaComparison_LessOrEqual 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_OPADD, // nzLuaOperation_Addition
LUA_OPDIV, // nzLuaOperation_Division LUA_OPDIV, // nzLuaOperation_Division
LUA_OPPOW, // nzLuaOperation_Exponentiation LUA_OPPOW, // nzLuaOperation_Exponentiation
@ -64,7 +66,9 @@ namespace
LUA_OPSUB // nzLuaOperation_Substraction 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_TBOOLEAN, // nzLuaType_Boolean
LUA_TFUNCTION, // nzLuaType_Function LUA_TFUNCTION, // nzLuaType_Function
LUA_TLIGHTUSERDATA, // nzLuaType_LightUserdata LUA_TLIGHTUSERDATA, // nzLuaType_LightUserdata
@ -76,6 +80,8 @@ namespace
LUA_TTHREAD, // nzLuaType_Thread LUA_TTHREAD, // nzLuaType_Thread
LUA_TUSERDATA // nzLuaType_Userdata LUA_TUSERDATA // nzLuaType_Userdata
}; };
static_assert(sizeof(s_types)/sizeof(int) == nzLuaType_Max+1, "Lua type array is incomplete");
} }
NzLuaInstance::NzLuaInstance() : NzLuaInstance::NzLuaInstance() :
@ -95,6 +101,26 @@ NzLuaInstance::~NzLuaInstance()
lua_close(m_state); 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 void NzLuaInstance::CheckAny(int index) const
{ {
luaL_checkany(m_state, index); luaL_checkany(m_state, index);
@ -224,6 +250,16 @@ void NzLuaInstance::Concatenate(int count)
lua_concat(m_state, 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 NzString NzLuaInstance::DumpStack() const
{ {
NzStringStream stream; NzStringStream stream;
@ -240,7 +276,7 @@ NzString NzLuaInstance::DumpStack() const
break; break;
case nzLuaType_Function: case nzLuaType_Function:
stream << "Function"; stream << "Function(" << ToPointer(i) << ')';
break; break;
case nzLuaType_LightUserdata: case nzLuaType_LightUserdata:
@ -265,15 +301,15 @@ NzString NzLuaInstance::DumpStack() const
break; break;
case nzLuaType_Table: case nzLuaType_Table:
stream << "Table"; stream << "Table(" << ToPointer(i) << ')';
break; break;
case nzLuaType_Thread: case nzLuaType_Thread:
stream << "Thread"; stream << "Thread(" << ToPointer(i) << ')';
break; break;
default: default:
stream << "Unknown"; stream << "Unknown(" << ToPointer(i) << ')';
break; break;
} }
@ -620,6 +656,11 @@ void NzLuaInstance::PushNumber(double value)
lua_pushnumber(m_state, value); lua_pushnumber(m_state, value);
} }
void NzLuaInstance::PushReference(int ref)
{
lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref);
}
void NzLuaInstance::PushString(const char* str) void NzLuaInstance::PushString(const char* str)
{ {
lua_pushstring(m_state, str); lua_pushstring(m_state, str);
@ -745,6 +786,11 @@ double NzLuaInstance::ToNumber(int index, bool* succeeded) const
return result; 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 const char* NzLuaInstance::ToString(int index, std::size_t* length) const
{ {
return lua_tolstring(m_state, index, length); return lua_tolstring(m_state, index, length);