Initial commit
This commit is contained in:
258
engines/grim/lua/lstate.cpp
Normal file
258
engines/grim/lua/lstate.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stdin
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stdout
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_stderror
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
|
||||
#define FORBIDDEN_SYMBOL_EXCEPTION_FILE
|
||||
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "engines/grim/debug.h"
|
||||
#include "engines/grim/actor.h"
|
||||
#include "engines/grim/color.h"
|
||||
|
||||
#include "engines/grim/lua/lbuiltin.h"
|
||||
#include "engines/grim/lua/ldo.h"
|
||||
#include "engines/grim/lua/lauxlib.h"
|
||||
#include "engines/grim/lua/lfunc.h"
|
||||
#include "engines/grim/lua/lgc.h"
|
||||
#include "engines/grim/lua/llex.h"
|
||||
#include "engines/grim/lua/lmem.h"
|
||||
#include "engines/grim/lua/lstate.h"
|
||||
#include "engines/grim/lua/lstring.h"
|
||||
#include "engines/grim/lua/ltable.h"
|
||||
#include "engines/grim/lua/ltask.h"
|
||||
#include "engines/grim/lua/ltm.h"
|
||||
#include "engines/grim/lua/lualib.h"
|
||||
#include "engines/grim/lua/luadebug.h"
|
||||
|
||||
namespace Grim {
|
||||
|
||||
GCnode rootproto;
|
||||
GCnode rootcl;
|
||||
GCnode rootglobal;
|
||||
GCnode roottable;
|
||||
struct ref *refArray;
|
||||
int32 refSize;
|
||||
int32 GCthreshold;
|
||||
int32 nblocks;
|
||||
int32 Mbuffsize;
|
||||
int32 Mbuffnext;
|
||||
char *Mbuffbase;
|
||||
char *Mbuffer;
|
||||
TObject errorim;
|
||||
stringtable *string_root;
|
||||
int32 last_tag;
|
||||
struct IM *IMtable;
|
||||
int32 IMtable_size;
|
||||
|
||||
LState *lua_state = nullptr;
|
||||
LState *lua_rootState = nullptr;
|
||||
|
||||
int globalTaskSerialId = 0;
|
||||
|
||||
void stderrorim();
|
||||
|
||||
static luaL_reg stdErrorRimFunc[] = {
|
||||
{ "stderrorim", stderrorim }
|
||||
};
|
||||
|
||||
static void lua_openthr() {
|
||||
Mbuffsize = 0;
|
||||
Mbuffnext = 0;
|
||||
Mbuffbase = nullptr;
|
||||
Mbuffer = nullptr;
|
||||
}
|
||||
|
||||
#define STACK_UNIT 256
|
||||
|
||||
void lua_stateinit(LState *state) {
|
||||
state->prev = nullptr;
|
||||
state->next = nullptr;
|
||||
state->all_paused = 0;
|
||||
state->paused = false;
|
||||
state->preventBreakCounter = 0;
|
||||
state->callLevelCounter = 0;
|
||||
state->updated = false;
|
||||
|
||||
state->numCblocks = 0;
|
||||
state->Cstack.base = 0;
|
||||
state->Cstack.lua2C = 0;
|
||||
state->Cstack.num = 0;
|
||||
state->errorJmp = nullptr;
|
||||
state->id = globalTaskSerialId++;
|
||||
state->task = nullptr;
|
||||
state->prevTask = nullptr;
|
||||
state->taskFunc.ttype = LUA_T_NIL;
|
||||
state->sleepFor = 0;
|
||||
|
||||
state->stack.stack = luaM_newvector(STACK_UNIT, TObject);
|
||||
state->stack.top = state->stack.stack;
|
||||
state->stack.last = state->stack.stack + (STACK_UNIT - 1);
|
||||
}
|
||||
|
||||
void lua_statedeinit(LState *state) {
|
||||
if (state->prev)
|
||||
state->prev->next = state->next;
|
||||
if (state->next)
|
||||
state->next->prev = state->prev;
|
||||
state->next = nullptr;
|
||||
state->prev = nullptr;
|
||||
|
||||
if (state->task) {
|
||||
lua_Task *t, *m;
|
||||
for (t = state->task; t != nullptr;) {
|
||||
m = t->next;
|
||||
luaM_free(t);
|
||||
t = m;
|
||||
}
|
||||
}
|
||||
|
||||
free(state->stack.stack);
|
||||
}
|
||||
|
||||
void lua_resetglobals() {
|
||||
lua_openthr();
|
||||
|
||||
rootproto.next = nullptr;
|
||||
rootproto.marked = 0;
|
||||
rootcl.next = nullptr;
|
||||
rootcl.marked = 0;
|
||||
rootglobal.next = nullptr;
|
||||
rootglobal.marked = 0;
|
||||
roottable.next = nullptr;
|
||||
roottable.marked = 0;
|
||||
refArray = nullptr;
|
||||
refSize = 0;
|
||||
GCthreshold = GARBAGE_BLOCK;
|
||||
nblocks = 0;
|
||||
|
||||
luaD_init();
|
||||
luaS_init();
|
||||
luaX_init();
|
||||
}
|
||||
|
||||
void callHook(lua_Function func, const char *filename, int32 line) {
|
||||
const char *name, *type;
|
||||
FILE *output = stdout;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lua_state->callLevelCounter; i++) {
|
||||
fprintf(output, " ");
|
||||
}
|
||||
fprintf(output, "id: %d ", lua_state->id);
|
||||
type = lua_getobjname(func, &name);
|
||||
if (func == LUA_NOOBJECT) {
|
||||
fprintf(output, "<< %s\n", filename);
|
||||
return;
|
||||
} else {
|
||||
fprintf(output, ">> %s ", filename);
|
||||
}
|
||||
|
||||
switch (*type) {
|
||||
case 'g':
|
||||
fprintf(output, "function: %s(", name);
|
||||
for (i = 1; ; i++) {
|
||||
if (lua_getparam(i) == LUA_NOOBJECT)
|
||||
break;
|
||||
if (lua_isnil(lua_getparam(i)))
|
||||
fprintf(output, "nil");
|
||||
else if (lua_istable(lua_getparam(i)))
|
||||
fprintf(output, "{...}");
|
||||
else if (lua_isuserdata(lua_getparam(i))) {
|
||||
if (lua_tag(lua_getparam(i)) == MKTAG('A','C','T','R')) {
|
||||
Actor *a = Actor::getPool().getObject(lua_getuserdata(lua_getparam(i)));
|
||||
fprintf(output, "<actor \"%s\">", a->getName().c_str());
|
||||
} else if (lua_tag(lua_getparam(i)) == MKTAG('C','O','L','R')) {
|
||||
Color c(lua_getuserdata(lua_getparam(i)));
|
||||
fprintf(output, "<color #%02x%02x%02x>", c.getRed(), c.getGreen(), c.getBlue());
|
||||
} else
|
||||
fprintf(output, "<userdata %d>", lua_getuserdata(lua_getparam(i)));
|
||||
} else if (lua_isfunction(lua_getparam(i))) {
|
||||
lua_getobjname(lua_getparam(i), &name);
|
||||
fprintf(output, "<function %s>", name);
|
||||
} else if (lua_isnumber(lua_getparam(i)))
|
||||
fprintf(output, "%g", lua_getnumber(lua_getparam(i)));
|
||||
else if (lua_isstring(lua_getparam(i)))
|
||||
fprintf(output, "\"%s\"", lua_getstring(lua_getparam(i)));
|
||||
else
|
||||
fprintf(output, "<unknown>");
|
||||
if (lua_getparam(i + 1) != LUA_NOOBJECT)
|
||||
fprintf(output, ", ");
|
||||
}
|
||||
fprintf(output, ")");
|
||||
break;
|
||||
case 't':
|
||||
fprintf(output, "`%s' tag method", name);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (line == 0)
|
||||
fprintf(output, "{START SCRIPT: %s}", filename);
|
||||
else if (line < 0) {
|
||||
fprintf(output, "Unknown %s", filename);
|
||||
} else
|
||||
fprintf(output, "function (%s:%d)", filename, line);
|
||||
}
|
||||
}
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
void lua_open() {
|
||||
if (lua_state)
|
||||
return;
|
||||
lua_rootState = lua_state = luaM_new(LState);
|
||||
lua_stateinit(lua_state);
|
||||
lua_resetglobals();
|
||||
luaT_init();
|
||||
luaB_predefine();
|
||||
luaL_addlibtolist(stdErrorRimFunc, (sizeof(stdErrorRimFunc) / sizeof(stdErrorRimFunc[0])));
|
||||
if (Debug::isChannelEnabled(Debug::Lua))
|
||||
lua_callhook = callHook;
|
||||
}
|
||||
|
||||
void lua_close() {
|
||||
TaggedString *alludata = luaS_collectudata();
|
||||
GCthreshold = MAX_INT; // to avoid GC during GC
|
||||
luaC_hashcallIM((Hash *)roottable.next); // GC t.methods for tables
|
||||
luaC_strcallIM(alludata); // GC tag methods for userdata
|
||||
luaD_gcIM(&luaO_nilobject); // GC tag method for nil (signal end of GC)
|
||||
luaH_free((Hash *)roottable.next);
|
||||
luaF_freeproto((TProtoFunc *)rootproto.next);
|
||||
luaF_freeclosure((Closure *)rootcl.next);
|
||||
luaS_free(alludata);
|
||||
luaS_freeall();
|
||||
luaM_free(IMtable);
|
||||
luaM_free(refArray);
|
||||
luaM_free(Mbuffer);
|
||||
|
||||
LState *tmpState, *state;
|
||||
for (state = lua_rootState; state != nullptr;) {
|
||||
tmpState = state->next;
|
||||
lua_statedeinit(state);
|
||||
luaM_free(state);
|
||||
state = tmpState;
|
||||
}
|
||||
|
||||
Mbuffer = nullptr;
|
||||
IMtable = nullptr;
|
||||
refArray = nullptr;
|
||||
lua_rootState = lua_state = nullptr;
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
printf("total de blocos: %ld\n", numblocks);
|
||||
printf("total de memoria: %ld\n", totalmem);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool lua_isopen() {
|
||||
return (lua_rootState);
|
||||
}
|
||||
|
||||
} // end of namespace Grim
|
||||
Reference in New Issue
Block a user