ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

lstate.cpp

Go to the documentation of this file.
00001 /*
00002 ** Global State
00003 ** See Copyright Notice in lua.h
00004 */
00005 
00006 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
00007 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
00008 #define FORBIDDEN_SYMBOL_EXCEPTION_stdin
00009 #define FORBIDDEN_SYMBOL_EXCEPTION_stdout
00010 #define FORBIDDEN_SYMBOL_EXCEPTION_stderror
00011 #define FORBIDDEN_SYMBOL_EXCEPTION_fprintf
00012 #define FORBIDDEN_SYMBOL_EXCEPTION_FILE
00013 
00014 #include "common/endian.h"
00015 
00016 #include "engines/grim/debug.h"
00017 #include "engines/grim/actor.h"
00018 #include "engines/grim/color.h"
00019 
00020 #include "engines/grim/lua/lbuiltin.h"
00021 #include "engines/grim/lua/ldo.h"
00022 #include "engines/grim/lua/lauxlib.h"
00023 #include "engines/grim/lua/lfunc.h"
00024 #include "engines/grim/lua/lgc.h"
00025 #include "engines/grim/lua/llex.h"
00026 #include "engines/grim/lua/lmem.h"
00027 #include "engines/grim/lua/lstate.h"
00028 #include "engines/grim/lua/lstring.h"
00029 #include "engines/grim/lua/ltable.h"
00030 #include "engines/grim/lua/ltask.h"
00031 #include "engines/grim/lua/ltm.h"
00032 #include "engines/grim/lua/lualib.h"
00033 #include "engines/grim/lua/luadebug.h"
00034 
00035 namespace Grim {
00036 
00037 GCnode rootproto;
00038 GCnode rootcl;
00039 GCnode rootglobal;
00040 GCnode roottable;
00041 struct ref *refArray;
00042 int32 refSize;
00043 int32 GCthreshold;
00044 int32 nblocks;
00045 int32 Mbuffsize;
00046 int32 Mbuffnext;
00047 char *Mbuffbase;
00048 char *Mbuffer;
00049 TObject errorim;
00050 stringtable *string_root;
00051 int32 last_tag;
00052 struct IM *IMtable;
00053 int32 IMtable_size;
00054 
00055 LState *lua_state = nullptr;
00056 LState *lua_rootState = nullptr;
00057 
00058 int globalTaskSerialId = 0;
00059 
00060 void stderrorim();
00061 
00062 static luaL_reg stdErrorRimFunc[] = {
00063     { "stderrorim", stderrorim }
00064 };
00065 
00066 static void lua_openthr() {
00067     Mbuffsize = 0;
00068     Mbuffnext = 0;
00069     Mbuffbase = nullptr;
00070     Mbuffer = nullptr;
00071 }
00072 
00073 #define STACK_UNIT  256
00074 
00075 void lua_stateinit(LState *state) {
00076     state->prev = nullptr;
00077     state->next = nullptr;
00078     state->all_paused = 0;
00079     state->paused = false;
00080     state->state_counter1 = 0;
00081     state->state_counter2 = 0;
00082     state->updated = false;
00083 
00084     state->numCblocks = 0;
00085     state->Cstack.base = 0;
00086     state->Cstack.lua2C = 0;
00087     state->Cstack.num = 0;
00088     state->errorJmp = nullptr;
00089     state->id = globalTaskSerialId++;
00090     state->task = nullptr;
00091     state->some_task = nullptr;
00092     state->taskFunc.ttype = LUA_T_NIL;
00093     state->sleepFor = 0;
00094 
00095     state->stack.stack = luaM_newvector(STACK_UNIT, TObject);
00096     state->stack.top = state->stack.stack;
00097     state->stack.last = state->stack.stack + (STACK_UNIT - 1);
00098 }
00099 
00100 void lua_statedeinit(LState *state) {
00101     if (state->prev)
00102         state->prev->next = state->next;
00103     if (state->next)
00104         state->next->prev = state->prev;
00105     state->next = nullptr;
00106     state->prev = nullptr;
00107 
00108     if (state->task) {
00109         lua_Task *t, *m;
00110         for (t = state->task; t != nullptr;) {
00111             m = t->next;
00112             luaM_free(t);
00113             t = m;
00114         }
00115     }
00116 
00117     free(state->stack.stack);
00118 }
00119 
00120 void lua_resetglobals() {
00121     lua_openthr();
00122 
00123     rootproto.next = nullptr;
00124     rootproto.marked = 0;
00125     rootcl.next = nullptr;
00126     rootcl.marked = 0;
00127     rootglobal.next = nullptr;
00128     rootglobal.marked = 0;
00129     roottable.next = nullptr;
00130     roottable.marked = 0;
00131     refArray = nullptr;
00132     refSize = 0;
00133     GCthreshold = GARBAGE_BLOCK;
00134     nblocks = 0;
00135 
00136     luaD_init();
00137     luaS_init();
00138     luaX_init();
00139 }
00140 
00141 void callHook(lua_Function func, const char *filename, int32 line) {
00142     const char *name, *type;
00143     FILE *output = stdout;
00144     int i;
00145 
00146     type = lua_getobjname(func, &name);
00147     if (func == LUA_NOOBJECT) {
00148         fprintf(output, "%s\n", filename);
00149         return;
00150     }
00151 
00152     switch (*type) {
00153     case 'g':
00154         fprintf(output, "function: %s(", name);
00155         for (i = 1; ; i++) {
00156             if (lua_getparam(i) == LUA_NOOBJECT)
00157                 break;
00158             if (lua_isnil(lua_getparam(i)))
00159                 fprintf(output, "nil");
00160             else if (lua_istable(lua_getparam(i)))
00161                 fprintf(output, "{...}");
00162             else if (lua_isuserdata(lua_getparam(i))) {
00163                 if (lua_tag(lua_getparam(i)) == MKTAG('A','C','T','R')) {
00164                     Actor *a = Actor::getPool().getObject(lua_getuserdata(lua_getparam(i)));
00165                     fprintf(output, "<actor \"%s\">", a->getName().c_str());
00166                 } else if (lua_tag(lua_getparam(i)) == MKTAG('C','O','L','R')) {
00167                     Color c(lua_getuserdata(lua_getparam(i)));
00168                     fprintf(output, "<color #%02x%02x%02x>", c.getRed(), c.getGreen(), c.getBlue());
00169                 } else
00170                     fprintf(output, "<userdata %d>", lua_getuserdata(lua_getparam(i)));
00171             } else if (lua_isfunction(lua_getparam(i))) {
00172                 fprintf(output, "<function>");
00173             } else if (lua_isnumber(lua_getparam(i)))
00174                 fprintf(output, "%g", lua_getnumber(lua_getparam(i)));
00175             else if (lua_isstring(lua_getparam(i)))
00176                 fprintf(output, "\"%s\"", lua_getstring(lua_getparam(i)));
00177             else
00178                 fprintf(output, "<unknown>");
00179             if (lua_getparam(i + 1) != LUA_NOOBJECT)
00180                 fprintf(output, ", ");
00181         }
00182         fprintf(output, ")");
00183             break;
00184     case 't':
00185         fprintf(output, "`%s' tag method", name);
00186         break;
00187     default:
00188         {
00189             if (line == 0)
00190                 fprintf(output, "{START SCRIPT: %s}", filename);
00191             else if (line < 0) {
00192                 fprintf(output, "%s", filename);
00193             } else
00194                 fprintf(output, "function (%s:%d)", filename, line);
00195         }
00196     }
00197     fprintf(output, "\n");
00198 }
00199 
00200 void lua_open() {
00201     if (lua_state)
00202         return;
00203     lua_rootState = lua_state = luaM_new(LState);
00204     lua_stateinit(lua_state);
00205     lua_resetglobals();
00206     luaT_init();
00207     luaB_predefine();
00208     luaL_addlibtolist(stdErrorRimFunc, (sizeof(stdErrorRimFunc) / sizeof(stdErrorRimFunc[0])));
00209     if (Debug::isChannelEnabled(Debug::Lua))
00210         lua_callhook = callHook;
00211 }
00212 
00213 void lua_close() {
00214     TaggedString *alludata = luaS_collectudata();
00215     GCthreshold = MAX_INT;  // to avoid GC during GC
00216     luaC_hashcallIM((Hash *)roottable.next);  // GC t.methods for tables
00217     luaC_strcallIM(alludata);  // GC tag methods for userdata
00218     luaD_gcIM(&luaO_nilobject);  // GC tag method for nil (signal end of GC)
00219     luaH_free((Hash *)roottable.next);
00220     luaF_freeproto((TProtoFunc *)rootproto.next);
00221     luaF_freeclosure((Closure *)rootcl.next);
00222     luaS_free(alludata);
00223     luaS_freeall();
00224     luaM_free(IMtable);
00225     luaM_free(refArray);
00226     luaM_free(Mbuffer);
00227 
00228     LState *tmpState, *state;
00229     for (state = lua_rootState; state != nullptr;) {
00230         tmpState = state->next;
00231         lua_statedeinit(state);
00232         luaM_free(state);
00233         state = tmpState;
00234     }
00235 
00236     Mbuffer = nullptr;
00237     IMtable = nullptr;
00238     refArray = nullptr;
00239     lua_rootState = lua_state = nullptr;
00240 
00241 #ifdef LUA_DEBUG
00242     printf("total de blocos: %ld\n", numblocks);
00243     printf("total de memoria: %ld\n", totalmem);
00244 #endif
00245 }
00246 
00247 bool lua_isopen() {
00248     return (lua_rootState);
00249 }
00250 
00251 } // end of namespace Grim


Generated on Sat May 25 2019 05:00:48 for ResidualVM by doxygen 1.7.1
curved edge   curved edge