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

ltm.cpp

Go to the documentation of this file.
00001 /*
00002 ** Tag methods
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_fprintf
00009 #define FORBIDDEN_SYMBOL_EXCEPTION_stderr
00010 
00011 #include "engines/grim/lua/lauxlib.h"
00012 #include "engines/grim/lua/lmem.h"
00013 #include "engines/grim/lua/lobject.h"
00014 #include "engines/grim/lua/lstate.h"
00015 #include "engines/grim/lua/ltm.h"
00016 #include "engines/grim/lua/lapi.h"
00017 
00018 namespace Grim {
00019 
00020 const char *luaT_eventname[] = {  // ORDER IM
00021     "gettable", "settable", "index", "getglobal", "setglobal", "add",
00022     "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge",
00023     "concat", "gc", "function", nullptr
00024 };
00025 
00026 static int32 luaI_checkevent(const char *name, const char *list[]) {
00027     int32 e = luaO_findstring(name, list);
00028     if (e < 0)
00029         luaL_verror("`%.50s' is not a valid event name", name);
00030     return e;
00031 }
00032 
00033 /* events in LUA_T_NIL are all allowed, since this is used as a
00034  *  'placeholder' for "default" fallbacks
00035  */
00036 static char validevents[NUM_TAGS][IM_N] = { // ORDER LUA_T, ORDER IM
00037     {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},  // LUA_T_USERDATA
00038     {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},  // LUA_T_NUMBER
00039     {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},  // LUA_T_STRING
00040     {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},  // LUA_T_ARRAY
00041     {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  // LUA_T_PROTO
00042     {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},  // LUA_T_CPROTO
00043     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},  // LUA_T_TASK
00044     {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}   // LUA_T_NIL
00045 };
00046 
00047 static int32 validevent(int32 t, int32 e) { // ORDER LUA_T
00048     return (t < LUA_T_NIL) ? 1 : validevents[-t][e];
00049 }
00050 
00051 static void init_entry(int32 tag) {
00052     int32 i;
00053     for (i = 0; i < IM_N; i++)
00054         ttype(luaT_getim(tag, i)) = LUA_T_NIL;
00055 }
00056 
00057 static bool tmFBAdded = false;
00058 
00059 void luaT_init() {
00060     int32 t;
00061     IMtable_size = NUM_TAGS * 2;
00062     last_tag = -(NUM_TAGS - 1);
00063     IMtable = luaM_newvector(IMtable_size, struct IM);
00064     for (t = -(IMtable_size - 1); t <= 0; t++)
00065         init_entry(t);
00066 
00067     tmFBAdded = false;
00068 }
00069 
00070 int32 lua_newtag() {
00071     --last_tag;
00072     if (-last_tag >= IMtable_size)
00073         IMtable_size = luaM_growvector(&IMtable, IMtable_size, struct IM, memEM, MAX_INT);
00074     init_entry(last_tag);
00075     return last_tag;
00076 }
00077 
00078 static void checktag(int32 tag) {
00079     if (!(last_tag <= tag && tag <= 0))
00080         luaL_verror("%d is not a valid tag", tag);
00081 }
00082 
00083 void luaT_realtag(int32 tag) {
00084     if (!(last_tag <= tag && tag < LUA_T_NIL))
00085         luaL_verror("tag %d is not result of `newtag'", tag);
00086 }
00087 
00088 int32 lua_copytagmethods(int32 tagto, int32 tagfrom) {
00089     int32 e;
00090     checktag(tagto);
00091     checktag(tagfrom);
00092     for (e = 0; e < IM_N; e++) {
00093         if (validevent(tagto, e))
00094             *luaT_getim(tagto, e) = *luaT_getim(tagfrom, e);
00095     }
00096     return tagto;
00097 }
00098 
00099 int32 luaT_efectivetag(TObject *o) {
00100     int32 t;
00101     switch (t = ttype(o)) {
00102     case LUA_T_ARRAY:
00103         return o->value.a->htag;
00104     case LUA_T_USERDATA:
00105         {
00106             int32 tag = o->value.ud.tag;
00107             return (tag >= 0) ? LUA_T_USERDATA : tag;
00108         }
00109     case LUA_T_CLOSURE:
00110         return o->value.cl->consts[0].ttype;
00111 #ifdef LUA_DEBUG
00112     case LUA_T_PMARK:
00113     case LUA_T_CMARK:
00114     case LUA_T_CLMARK:
00115     case LUA_T_LINE:
00116         lua_error("internal error");
00117 #endif
00118     default:
00119         return t;
00120     }
00121 }
00122 
00123 TObject *luaT_gettagmethod(int32 t, const char *event) {
00124     int32 e = luaI_checkevent(event, luaT_eventname);
00125     checktag(t);
00126     if (validevent(t, e))
00127         return luaT_getim(t,e);
00128     else
00129         return &luaO_nilobject;
00130 }
00131 
00132 void luaT_settagmethod(int32 t, const char *event, TObject *func) {
00133     TObject temp = *func;
00134     int32 e = luaI_checkevent(event, luaT_eventname);
00135     checktag(t);
00136     if (!validevent(t, e))
00137         luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d",
00138         luaT_eventname[e], t);
00139     *func = *luaT_getim(t,e);
00140     *luaT_getim(t, e) = temp;
00141 }
00142 
00143 const char *luaT_travtagmethods(int32 (*fn)(TObject *)) {
00144     int32 e;
00145     if (fn(&errorim))
00146         return "error";
00147     for (e = IM_GETTABLE; e <= IM_FUNCTION; e++) {  // ORDER IM
00148         int32 t;
00149         for (t = 0; t >= last_tag; t--)
00150             if (fn(luaT_getim(t, e)))
00151                 return luaT_eventname[e];
00152     }
00153     return nullptr;
00154 }
00155 
00156 /*
00157 * compatibility with old fallback system
00158 */
00159 #ifdef LUA_COMPAT2_5
00160 
00161 void errorFB() {
00162     lua_Object o = lua_getparam(1);
00163     if (lua_isstring(o))
00164         fprintf(stderr, "lua: %s\n", lua_getstring(o));
00165     else
00166         fprintf(stderr, "lua: unknown error\n");
00167 }
00168 
00169 void nilFB() { }
00170 
00171 void typeFB () {
00172     lua_error("unexpected type");
00173 }
00174 
00175 static void fillvalids(IMS e, TObject *func) {
00176     int32 t;
00177     for (t = LUA_T_NIL; t <= LUA_T_USERDATA; t++)
00178         if (validevent(t, e))
00179             *luaT_getim(t, e) = *func;
00180 }
00181 
00182 static luaL_reg tmFB[] = {
00183     {"  typeFB", typeFB},
00184     {"  errorFB", errorFB},
00185     {"  nilFB", nilFB}
00186 };
00187 
00188 void luaT_setfallback() {
00189     static const char *oldnames [] = { "error", "getglobal", "arith", "order", nullptr };
00190     TObject oldfunc;
00191     lua_CFunction replace;
00192     if (!tmFBAdded) {
00193         luaL_addlibtolist(tmFB, (sizeof(tmFB) / sizeof(tmFB[0])));
00194         tmFBAdded = true;
00195     }
00196     const char *name = luaL_check_string(1);
00197     lua_Object func = lua_getparam(2);
00198     luaL_arg_check(lua_isfunction(func), 2, "function expected");
00199     switch (luaO_findstring(name, oldnames)) {
00200     case 0:  // old error fallback
00201         oldfunc = errorim;
00202         errorim = *luaA_Address(func);
00203         replace = errorFB;
00204         break;
00205     case 1:  // old getglobal fallback
00206         oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL);
00207         *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func);
00208         replace = nilFB;
00209         break;
00210     case 2:
00211         {  // old arith fallback
00212             int32 i;
00213             oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW);
00214             for (i = IM_ADD; i <= IM_UNM; i++)  // ORDER IM
00215                 fillvalids(i, luaA_Address(func));
00216             replace = typeFB;
00217             break;
00218         }
00219     case 3:
00220         {  // old order fallback
00221             int32 i;
00222             oldfunc = *luaT_getim(LUA_T_NIL, IM_LT);
00223             for (i = IM_LT; i <= IM_GE; i++)  // ORDER IM
00224                 fillvalids(i, luaA_Address(func));
00225             replace = typeFB;
00226             break;
00227         }
00228     default:
00229         {
00230             int32 e;
00231             if ((e = luaO_findstring(name, luaT_eventname)) >= 0) {
00232                 oldfunc = *luaT_getim(LUA_T_NIL, e);
00233                 fillvalids(e, luaA_Address(func));
00234                 replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB;
00235             } else {
00236                 luaL_verror("`%.50s' is not a valid fallback name", name);
00237                 replace = nullptr;  // to avoid warnings
00238                 oldfunc.ttype = LUA_T_NIL; // to avoid warnings
00239             }
00240         }
00241     }
00242     if (oldfunc.ttype != LUA_T_NIL)
00243         luaA_pushobject(&oldfunc);
00244     else
00245         lua_pushcfunction(replace);
00246 }
00247 
00248 #endif
00249 
00250 } // end of namespace Grim


Generated on Sat Feb 16 2019 05:00:56 for ResidualVM by doxygen 1.7.1
curved edge   curved edge