00001
00002
00003
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;
00216 luaC_hashcallIM((Hash *)roottable.next);
00217 luaC_strcallIM(alludata);
00218 luaD_gcIM(&luaO_nilobject);
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 }