|
|
|
@ -23,20 +23,14 @@
|
|
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
|
{
|
|
|
|
|
#ifdef max
|
|
|
|
|
# undef max
|
|
|
|
|
#endif
|
|
|
|
|
#include "lualib.h"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
# ifndef NL_EXTENDED_FOR_SCOPE
|
|
|
|
|
# undef for
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
#undef new
|
|
|
|
|
// to get rid of you_must_not_use_assert___use_nl_assert___read_debug_h_file messages
|
|
|
|
|
#include <cassert>
|
|
|
|
|
#undef assert
|
|
|
|
|
#define assert nlassert
|
|
|
|
|
#include <luabind/luabind.hpp>
|
|
|
|
|
#define new NL_NEW
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
using namespace NLMISC;
|
|
|
|
@ -58,25 +52,86 @@ void CLuaStackChecker::decrementExceptionContextCounter()
|
|
|
|
|
-- _ExceptionContextCounter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
ILuaIDEInterface *LuaDebuggerIDE = NULL;
|
|
|
|
|
static bool LuaDebuggerVisible = false;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
HMODULE LuaDebuggerModule = 0;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void luaDebuggerMainLoop()
|
|
|
|
|
{
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
if (!LuaDebuggerIDE) return;
|
|
|
|
|
if (!LuaDebuggerVisible)
|
|
|
|
|
{
|
|
|
|
|
LuaDebuggerIDE->showDebugger(true);
|
|
|
|
|
LuaDebuggerIDE->expandProjectTree();
|
|
|
|
|
LuaDebuggerIDE->sortFiles();
|
|
|
|
|
LuaDebuggerVisible = true;
|
|
|
|
|
}
|
|
|
|
|
LuaDebuggerIDE->doMainLoop();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static std::allocator<uint8> l_stlAlloc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void l_free_func(void *block, int oldSize)
|
|
|
|
|
{
|
|
|
|
|
l_stlAlloc.deallocate((uint8 *) block, oldSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void *l_realloc_func(void *b, int os, int s)
|
|
|
|
|
{
|
|
|
|
|
if (os == s) return b;
|
|
|
|
|
void *newB = l_stlAlloc.allocate(s);
|
|
|
|
|
memcpy(newB, b, std::min(os, s));
|
|
|
|
|
l_free_func(b, os);
|
|
|
|
|
return newB;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const int MinGCThreshold = 128; // min value at which garbage collector will be triggered (in kilobytes)
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
CLuaState::CLuaState()
|
|
|
|
|
{
|
|
|
|
|
_State = NULL;
|
|
|
|
|
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
_State = lua_open(NULL, NULL);
|
|
|
|
|
_GCThreshold = MinGCThreshold;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (!_State)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
_State = lua_open(l_realloc_func, l_free_func);
|
|
|
|
|
#else
|
|
|
|
|
_State = lua_open();
|
|
|
|
|
#endif
|
|
|
|
|
nlassert(_State);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// *** Load base libs
|
|
|
|
|
{
|
|
|
|
|
CLuaStackChecker lsc(this);
|
|
|
|
|
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
|
|
|
|
luaL_openlibs(_State);
|
|
|
|
|
#else
|
|
|
|
|
luaopen_base (_State);
|
|
|
|
|
luaopen_table (_State);
|
|
|
|
|
luaopen_io (_State);
|
|
|
|
|
luaopen_string (_State);
|
|
|
|
|
luaopen_math (_State);
|
|
|
|
|
luaopen_debug (_State);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// open are buggy????
|
|
|
|
|
clear();
|
|
|
|
|
}
|
|
|
|
@ -122,11 +177,43 @@ CLuaStackRestorer::~CLuaStackRestorer()
|
|
|
|
|
_State->setTop(_FinalSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
static int NoOpReportHook( int /* reportType */, char * /* message */, int * /* returnValue */ )
|
|
|
|
|
{
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
CLuaState::~CLuaState()
|
|
|
|
|
{
|
|
|
|
|
nlassert(_State);
|
|
|
|
|
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
if (!LuaDebuggerIDE)
|
|
|
|
|
#else
|
|
|
|
|
if (1)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
lua_close(_State);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
LuaDebuggerIDE->stopDebug(); // this will also close the lua state
|
|
|
|
|
LuaDebuggerIDE = NULL;
|
|
|
|
|
LuaDebuggerVisible = false;
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
nlassert(LuaDebuggerModule)
|
|
|
|
|
_CrtSetReportHook(NoOpReportHook); // prevent dump of memory leaks at this point
|
|
|
|
|
//::FreeLibrary(LuaDebuggerModule); // don't free the library now (seems that it destroy, the main window, causing
|
|
|
|
|
// a crash when the app window is destroyed for real...
|
|
|
|
|
// -> FreeLibrary will be called when the application is closed
|
|
|
|
|
LuaDebuggerModule = 0;
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clear Small Script Cache
|
|
|
|
|
_SmallScriptPool= 0;
|
|
|
|
@ -161,9 +248,10 @@ struct CLuaReader
|
|
|
|
|
|
|
|
|
|
void CLuaState::loadScript(const std::string &code, const std::string &dbgSrc)
|
|
|
|
|
{
|
|
|
|
|
if (code.empty()) return;
|
|
|
|
|
struct CHelper
|
|
|
|
|
{
|
|
|
|
|
static const char *luaChunkReaderFromString(lua_State *L, void *ud, size_t *sz)
|
|
|
|
|
static const char *luaChunkReaderFromString(lua_State * /* L */, void *ud, size_t *sz)
|
|
|
|
|
{
|
|
|
|
|
CLuaReader *rd = (CLuaReader *) ud;
|
|
|
|
|
if (!rd->Done)
|
|
|
|
@ -182,6 +270,7 @@ void CLuaState::loadScript(const std::string &code, const std::string &dbgSrc)
|
|
|
|
|
CLuaReader rd;
|
|
|
|
|
rd.Str = &code;
|
|
|
|
|
rd.Done = false;
|
|
|
|
|
|
|
|
|
|
int result = lua_load(_State, CHelper::luaChunkReaderFromString, (void *) &rd, dbgSrc.c_str());
|
|
|
|
|
if (result !=0)
|
|
|
|
|
{
|
|
|
|
@ -241,6 +330,15 @@ bool CLuaState::executeFile(const std::string &pathName)
|
|
|
|
|
if(!inputFile.open(pathName))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
if (LuaDebuggerIDE)
|
|
|
|
|
{
|
|
|
|
|
std::string path = NLMISC::CPath::getCurrentPath() + "/" + pathName.c_str();
|
|
|
|
|
path = CPath::standardizeDosPath(path);
|
|
|
|
|
LuaDebuggerIDE->addFile(path.c_str());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// load the script text
|
|
|
|
|
string script;
|
|
|
|
|
/*
|
|
|
|
@ -253,7 +351,7 @@ bool CLuaState::executeFile(const std::string &pathName)
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
script.resize(NLMISC::CFile::getFileSize(pathName));
|
|
|
|
|
inputFile.serialBuffer((uint8 *) &script[0], script.size());
|
|
|
|
|
inputFile.serialBuffer((uint8 *) &script[0], (uint)script.size());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// execute the script text, with dbgSrc==filename (use @ for lua internal purpose)
|
|
|
|
@ -265,6 +363,7 @@ bool CLuaState::executeFile(const std::string &pathName)
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
void CLuaState::executeSmallScript(const std::string &script)
|
|
|
|
|
{
|
|
|
|
|
if (script.empty()) return;
|
|
|
|
|
// *** if the small script has not already been called before, parse it now
|
|
|
|
|
TSmallScriptCache::iterator it= _SmallScriptCache.find(script);
|
|
|
|
|
if(it==_SmallScriptCache.end())
|
|
|
|
@ -311,7 +410,6 @@ void CLuaState::executeSmallScript(const std::string &script)
|
|
|
|
|
// Stack: 1:NelTable
|
|
|
|
|
pop(); // ....
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
@ -528,7 +626,8 @@ CLuaStackChecker::~CLuaStackChecker()
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
void ELuaWrappedFunctionException::init(CLuaState *ls, const std::string &reason)
|
|
|
|
|
{
|
|
|
|
|
/* // Print first Lua Stack Context
|
|
|
|
|
// Print first Lua Stack Context
|
|
|
|
|
/*
|
|
|
|
|
CInterfaceManager *pIM= CInterfaceManager::getInstance();
|
|
|
|
|
if(ls)
|
|
|
|
|
{
|
|
|
|
@ -536,9 +635,9 @@ void ELuaWrappedFunctionException::init(CLuaState *ls, const std::string &reason
|
|
|
|
|
// enclose with cool colors
|
|
|
|
|
pIM->formatLuaStackContext(_Reason);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
// Append the reason
|
|
|
|
|
_Reason+= reason;*/
|
|
|
|
|
_Reason+= reason;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
@ -556,8 +655,72 @@ ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState,
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
ELuaWrappedFunctionException::ELuaWrappedFunctionException(CLuaState *luaState, const char *format, ...)
|
|
|
|
|
{
|
|
|
|
|
//H_AUTO(Lua_ELuaWrappedFunctionException_ELuaWrappedFunctionException)
|
|
|
|
|
std::string reason;
|
|
|
|
|
NLMISC_CONVERT_VARGS (reason, format, NLMISC::MaxCStringSize);
|
|
|
|
|
init(luaState, reason);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//================================================================================
|
|
|
|
|
void CLuaState::newTable()
|
|
|
|
|
{
|
|
|
|
|
nlverify( lua_checkstack(_State, 1) );
|
|
|
|
|
lua_newtable(_State);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//================================================================================
|
|
|
|
|
int CLuaState::getGCCount()
|
|
|
|
|
{
|
|
|
|
|
return lua_getgccount(_State);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//================================================================================
|
|
|
|
|
int CLuaState::getGCThreshold()
|
|
|
|
|
{
|
|
|
|
|
//H_AUTO(Lua_CLuaState_getGCThreshold)
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
return _GCThreshold;
|
|
|
|
|
#else
|
|
|
|
|
# if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
|
|
|
|
return lua_gc(_State, LUA_GCCOUNT, 0);
|
|
|
|
|
# else
|
|
|
|
|
return lua_getgcthreshold(_State);
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//================================================================================
|
|
|
|
|
void CLuaState::setGCThreshold(int kb)
|
|
|
|
|
{
|
|
|
|
|
//H_AUTO(Lua_CLuaState_setGCThreshold)
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
_GCThreshold = kb;
|
|
|
|
|
handleGC();
|
|
|
|
|
#else
|
|
|
|
|
# if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
|
|
|
|
|
lua_gc(_State, LUA_GCCOLLECT, kb);
|
|
|
|
|
# else
|
|
|
|
|
lua_setgcthreshold(_State, kb);
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//================================================================================
|
|
|
|
|
void CLuaState::handleGC()
|
|
|
|
|
{
|
|
|
|
|
//H_AUTO(Lua_CLuaState_handleGC)
|
|
|
|
|
#ifdef LUA_NEVRAX_VERSION
|
|
|
|
|
// must handle gc manually with the refcounted version
|
|
|
|
|
int gcCount = getGCCount();
|
|
|
|
|
if (gcCount >= _GCThreshold)
|
|
|
|
|
{
|
|
|
|
|
nlwarning("Triggering GC : memory in use = %d kb, current threshold = %d kb", gcCount, _GCThreshold);
|
|
|
|
|
lua_setgcthreshold(_State, 0);
|
|
|
|
|
gcCount = getGCCount();
|
|
|
|
|
_GCThreshold = std::max(MinGCThreshold, gcCount * 2);
|
|
|
|
|
nlwarning("After GC : memory in use = %d kb, threshold = %d kb", gcCount, _GCThreshold);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|