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

lapi.cpp

Go to the documentation of this file.
00001 /*
00002 ** Lua API
00003 ** See Copyright Notice in lua.h
00004 */
00005 
00006 #define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
00007 #define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
00008 
00009 #include "engines/grim/lua/lapi.h"
00010 #include "engines/grim/lua/lauxlib.h"
00011 #include "engines/grim/lua/ldo.h"
00012 #include "engines/grim/lua/lfunc.h"
00013 #include "engines/grim/lua/lgc.h"
00014 #include "engines/grim/lua/lmem.h"
00015 #include "engines/grim/lua/lobject.h"
00016 #include "engines/grim/lua/lstate.h"
00017 #include "engines/grim/lua/lstring.h"
00018 #include "engines/grim/lua/ltable.h"
00019 #include "engines/grim/lua/ltm.h"
00020 #include "engines/grim/lua/lua.h"
00021 #include "engines/grim/lua/luadebug.h"
00022 #include "engines/grim/lua/lvm.h"
00023 
00024 
00025 namespace Grim {
00026 
00027 char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
00028 "$Autores:  " LUA_AUTHORS " $";
00029 
00030 
00031 
00032 TObject *luaA_Address(lua_Object o) {
00033     return Address(o);
00034 }
00035 
00036 static int32 normalized_type(TObject *o) {
00037     int32 t = ttype(o);
00038     switch (t) {
00039     case LUA_T_PMARK:
00040         return LUA_T_PROTO;
00041     case LUA_T_CMARK:
00042         return LUA_T_CPROTO;
00043     case LUA_T_CLMARK:
00044         return LUA_T_CLOSURE;
00045     default:
00046         return t;
00047     }
00048 }
00049 
00050 void set_normalized(TObject *d, TObject *s) {
00051     d->value = s->value;
00052     d->ttype = (lua_Type)normalized_type(s);
00053 }
00054 
00055 static TObject *luaA_protovalue (TObject *o) {
00056     return (normalized_type(o) == LUA_T_CLOSURE) ?  protovalue(o) : o;
00057 }
00058 
00059 void luaA_packresults() {
00060     luaV_pack(lua_state->Cstack.lua2C, lua_state->Cstack.num, lua_state->stack.top);
00061     incr_top;
00062 }
00063 
00064 int32 luaA_passresults() {
00065     luaD_checkstack(lua_state->Cstack.num);
00066     memcpy(lua_state->stack.top, lua_state->Cstack.lua2C + lua_state->stack.stack, lua_state->Cstack.num * sizeof(TObject));
00067     lua_state->stack.top += lua_state->Cstack.num;
00068     return lua_state->Cstack.num;
00069 }
00070 
00071 static void checkCparams(int32 nParams) {
00072     if (lua_state->stack.top - lua_state->stack.stack < lua_state->Cstack.base + nParams)
00073         lua_error("API error - wrong number of arguments in C2lua stack");
00074 }
00075 
00076 static lua_Object put_luaObject(TObject *o) {
00077     luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - lua_state->Cstack.base);
00078     lua_state->stack.stack[lua_state->Cstack.base++] = *o;
00079 
00080     return lua_state->Cstack.base;  // this is +1 real position (see Ref)
00081 }
00082 
00083 static lua_Object put_luaObjectonTop() {
00084     luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - lua_state->Cstack.base);
00085     lua_state->stack.stack[lua_state->Cstack.base++] = *(--lua_state->stack.top);
00086     return lua_state->Cstack.base;  // this is +1 real position (see Ref)
00087 }
00088 
00089 lua_Object lua_pop() {
00090     checkCparams(1);
00091     return put_luaObjectonTop();
00092 }
00093 
00094 /*
00095 ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
00096 ** 'number' must be 1 to get the first parameter.
00097 */
00098 lua_Object lua_lua2C(int32 number) {
00099     if (number <= 0 || number > lua_state->Cstack.num)
00100         return LUA_NOOBJECT;
00101     return lua_state->Cstack.lua2C + number;
00102 }
00103 
00104 int32 lua_callfunction(lua_Object function) {
00105     if (function == LUA_NOOBJECT) {
00106         return 1;
00107     } else {
00108         luaD_openstack((lua_state->stack.top - lua_state->stack.stack) - lua_state->Cstack.base);
00109         set_normalized(lua_state->stack.stack + lua_state->Cstack.base, Address(function));
00110         return luaD_protectedrun(MULT_RET);
00111     }
00112 }
00113 
00114 lua_Object lua_gettagmethod(int32 tag, const char *event) {
00115     return put_luaObject(luaT_gettagmethod(tag, event));
00116 }
00117 
00118 lua_Object lua_settagmethod(int32 tag, const char *event) {
00119     checkCparams(1);
00120     luaT_settagmethod(tag, event, lua_state->stack.top - 1);
00121     return put_luaObjectonTop();
00122 }
00123 
00124 lua_Object lua_seterrormethod() {
00125     TObject temp = errorim;
00126     checkCparams(1);
00127     errorim = *(--lua_state->stack.top);
00128     return put_luaObject(&temp);
00129 }
00130 
00131 lua_Object lua_gettable() {
00132     checkCparams(2);
00133     luaV_gettable();
00134     return put_luaObjectonTop();
00135 }
00136 
00137 lua_Object lua_rawgettable() {
00138     checkCparams(2);
00139     if (ttype(lua_state->stack.top-2) != LUA_T_ARRAY) {
00140         lua_error("indexed expression not a table in rawgettable");
00141     } else {
00142         TObject *h = luaH_get(avalue(lua_state->stack.top - 2), lua_state->stack.top - 1);
00143         --lua_state->stack.top;
00144         if (h) {
00145             *(lua_state->stack.top-1) = *h;
00146         } else {
00147             ttype(lua_state->stack.top-1) = LUA_T_NIL;
00148         }
00149     }
00150     return put_luaObjectonTop();
00151 }
00152 
00153 void lua_settable() {
00154     checkCparams(3);
00155     luaV_settable(lua_state->stack.top-3, 1);
00156 }
00157 
00158 void lua_rawsettable() {
00159     checkCparams(3);
00160     luaV_settable(lua_state->stack.top-3, 0);
00161 }
00162 
00163 lua_Object lua_createtable() {
00164     TObject o;
00165     luaC_checkGC();
00166     avalue(&o) = luaH_new(0);
00167     ttype(&o) = LUA_T_ARRAY;
00168     return put_luaObject(&o);
00169 }
00170 
00171 lua_Object lua_getglobal(const char *name) {
00172     luaD_checkstack(2);  // may need that to call T.M.
00173     luaV_getglobal(luaS_new(name));
00174     return put_luaObjectonTop();
00175 }
00176 
00177 lua_Object lua_rawgetglobal(const char *name) {
00178     TaggedString *ts = luaS_new(name);
00179     return put_luaObject(&ts->globalval);
00180 }
00181 
00182 void lua_setglobal(const char *name) {
00183     checkCparams(1);
00184     luaD_checkstack(2);  // may need that to call T.M.
00185     luaV_setglobal(luaS_new(name));
00186 }
00187 
00188 void lua_rawsetglobal(const char *name) {
00189     TaggedString *ts = luaS_new(name);
00190     checkCparams(1);
00191     luaS_rawsetglobal(ts, --lua_state->stack.top);
00192 }
00193 
00194 int32 lua_isnil(lua_Object o) {
00195     return (o == LUA_NOOBJECT) || (ttype(Address(o)) == LUA_T_NIL);
00196 }
00197 
00198 int32 lua_istable(lua_Object o) {
00199     return (o != LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_ARRAY);
00200 }
00201 
00202 int32 lua_isuserdata(lua_Object o) {
00203     return (o != LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_USERDATA);
00204 }
00205 
00206 int32 lua_iscfunction(lua_Object o) {
00207     return (lua_tag(o) == LUA_T_CPROTO);
00208 }
00209 
00210 int32 lua_isnumber(lua_Object o) {
00211     return (o!= LUA_NOOBJECT) && (tonumber(Address(o)) == 0);
00212 }
00213 
00214 int32 lua_isstring(lua_Object o) {
00215     int32 t = lua_tag(o);
00216     return (t == LUA_T_STRING) || (t == LUA_T_NUMBER);
00217 }
00218 
00219 int32 lua_isfunction(lua_Object o) {
00220     int32 t = lua_tag(o);
00221     return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
00222 }
00223 
00224 float lua_getnumber(lua_Object object) {
00225     if (object == LUA_NOOBJECT)
00226         return 0.0f;
00227     if (tonumber(Address(object)))
00228         return 0.0f;
00229     else
00230         return (nvalue(Address(object)));
00231 }
00232 
00233 const char *lua_getstring (lua_Object object) {
00234     if (object == LUA_NOOBJECT || tostring(Address(object)))
00235         return nullptr;
00236     else
00237         return (svalue(Address(object)));
00238 }
00239 
00240 int32 lua_getuserdata(lua_Object object) {
00241     if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
00242         return 0;
00243     else
00244         return (Address(object))->value.ud.id;
00245 }
00246 
00247 lua_CFunction lua_getcfunction(lua_Object object) {
00248     if (!lua_iscfunction(object))
00249         return nullptr;
00250     else
00251         return fvalue(luaA_protovalue(Address(object)));
00252 }
00253 
00254 void lua_pushnil() {
00255     ttype(lua_state->stack.top) = LUA_T_NIL;
00256     incr_top;
00257 }
00258 
00259 void lua_pushnumber(float n) {
00260     ttype(lua_state->stack.top) = LUA_T_NUMBER;
00261     nvalue(lua_state->stack.top) = n;
00262     incr_top;
00263 }
00264 
00265 void lua_pushstring(const char *s) {
00266     if (!s)
00267         ttype(lua_state->stack.top) = LUA_T_NIL;
00268     else {
00269         tsvalue(lua_state->stack.top) = luaS_new(s);
00270         ttype(lua_state->stack.top) = LUA_T_STRING;
00271     }
00272     incr_top;
00273     luaC_checkGC();
00274 }
00275 
00276 void lua_pushCclosure(lua_CFunction fn, int32 n) {
00277     if (!fn)
00278         lua_error("API error - attempt to push a NULL Cfunction");
00279     checkCparams(n);
00280     ttype(lua_state->stack.top) = LUA_T_CPROTO;
00281     fvalue(lua_state->stack.top) = fn;
00282     incr_top;
00283     luaV_closure(n);
00284 }
00285 
00286 void lua_pushusertag(int32 u, int32 tag) {
00287     if (tag < 0 && tag != LUA_ANYTAG)
00288         luaT_realtag(tag);  // error if tag is not valid
00289     lua_state->stack.top->value.ud.id = u;
00290     lua_state->stack.top->value.ud.tag = tag;
00291     ttype(lua_state->stack.top) = LUA_T_USERDATA;
00292     incr_top;
00293     luaC_checkGC();
00294 }
00295 
00296 void luaA_pushobject(TObject *o) {
00297     *lua_state->stack.top = *o;
00298     incr_top;
00299 }
00300 
00301 void lua_pushobject(lua_Object o) {
00302     if (o == LUA_NOOBJECT)
00303         lua_error("API error - attempt to push a NOOBJECT");
00304     else {
00305         set_normalized(lua_state->stack.top, Address(o));
00306         incr_top;
00307     }
00308 }
00309 
00310 
00311 int32 lua_tag(lua_Object lo) {
00312     if (lo == LUA_NOOBJECT)
00313         return LUA_T_NIL;
00314     else {
00315         TObject *o = Address(lo);
00316         int32 t;
00317         switch (t = ttype(o)) {
00318         case LUA_T_USERDATA:
00319             return o->value.ud.tag;
00320         case LUA_T_ARRAY:
00321             return o->value.a->htag;
00322         case LUA_T_PMARK:
00323             return LUA_T_PROTO;
00324         case LUA_T_CMARK:
00325             return LUA_T_CPROTO;
00326         case LUA_T_CLOSURE: case LUA_T_CLMARK:
00327             return o->value.cl->consts[0].ttype;
00328 #ifdef LUA_DEBUG
00329         case LUA_T_LINE:
00330             LUA_INTERNALERROR("internal error");
00331 #endif
00332         default:
00333             return t;
00334         }
00335     }
00336 }
00337 
00338 void lua_settag(int32 tag) {
00339     checkCparams(1);
00340     luaT_realtag(tag);
00341     switch (ttype(lua_state->stack.top - 1)) {
00342     case LUA_T_ARRAY:
00343         (lua_state->stack.top - 1)->value.a->htag = tag;
00344         break;
00345     case LUA_T_USERDATA:
00346         (lua_state->stack.top - 1)->value.ud.tag = tag;
00347         break;
00348     default:
00349         luaL_verror("cannot change the tag of a %.20s", luaO_typenames[-ttype((lua_state->stack.top - 1))]);
00350     }
00351     lua_state->stack.top--;
00352 }
00353 
00354 /*
00355 ** =======================================================
00356 ** Debug interface
00357 ** =======================================================
00358 */
00359 
00360 // Hooks
00361 lua_CHFunction lua_callhook = nullptr;
00362 lua_LHFunction lua_linehook = nullptr;
00363 
00364 lua_Function lua_stackedfunction(int32 level) {
00365     StkId i;
00366     for (i = (lua_state->stack.top - 1) - lua_state->stack.stack; i >= 0; i--) {
00367         int32 t = lua_state->stack.stack[i].ttype;
00368         if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
00369             if (level-- == 0)
00370                 return Ref(lua_state->stack.stack + i);
00371     }
00372     return LUA_NOOBJECT;
00373 }
00374 
00375 int32 lua_currentline(lua_Function func) {
00376     TObject *f = Address(func);
00377     return (f + 1 < lua_state->stack.top && (f + 1)->ttype == LUA_T_LINE) ? (f + 1)->value.i : -1;
00378 }
00379 
00380 lua_Object lua_getlocal(lua_Function func, int32 local_number, char **name) {
00381     // check whether func is a Lua function
00382     if (lua_tag(func) != LUA_T_PROTO)
00383         return LUA_NOOBJECT;
00384     else {
00385         TObject *f = Address(func);
00386         TProtoFunc *fp = luaA_protovalue(f)->value.tf;
00387         *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
00388         if (*name) {
00389             // if "*name", there must be a LUA_T_LINE
00390             // therefore, f + 2 points to function base
00391             return Ref((f + 2) + (local_number - 1));
00392         } else
00393             return LUA_NOOBJECT;
00394     }
00395 }
00396 
00397 int32 lua_setlocal(lua_Function func, int32 local_number) {
00398     // check whether func is a Lua function
00399     if (lua_tag(func) != LUA_T_PROTO)
00400         return 0;
00401     else {
00402         TObject *f = Address(func);
00403         TProtoFunc *fp = luaA_protovalue(f)->value.tf;
00404         char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
00405         checkCparams(1);
00406         --lua_state->stack.top;
00407         if (name) {
00408             // if "name", there must be a LUA_T_LINE
00409             // therefore, f+2 points to function base
00410             *((f + 2) + (local_number - 1)) = *lua_state->stack.top;
00411             return 1;
00412         } else
00413             return 0;
00414     }
00415 }
00416 
00417 void lua_funcinfo(lua_Object func, const char **filename, int32 *linedefined) {
00418     if (!lua_isfunction(func))
00419         lua_error("API - `funcinfo' called with a non-function value");
00420     else {
00421         TObject *f = luaA_protovalue(Address(func));
00422         if (normalized_type(f) == LUA_T_PROTO) {
00423             *filename = tfvalue(f)->fileName->str;
00424             *linedefined = tfvalue(f)->lineDefined;
00425         } else {
00426             *filename = "(C)";
00427             *linedefined = -1;
00428         }
00429     }
00430 }
00431 
00432 static int32 checkfunc (TObject *o) {
00433     return luaO_equalObj(o, lua_state->stack.top);
00434 }
00435 
00436 const char *lua_getobjname (lua_Object o, const char **name) {
00437     // try to find a name for given function
00438     set_normalized(lua_state->stack.top, Address(o)); // to be accessed by "checkfunc
00439     *name = luaT_travtagmethods(checkfunc);
00440     if (*name)
00441         return "tag-method";
00442     *name = luaS_travsymbol(checkfunc);
00443     if (*name)
00444         return "global";
00445     else
00446         return "";
00447 }
00448 
00449 /*
00450 ** =======================================================
00451 ** BLOCK mechanism
00452 ** =======================================================
00453 */
00454 
00455 void lua_beginblock() {
00456     if (lua_state->numCblocks >= MAX_C_BLOCKS)
00457         lua_error("too many nested blocks");
00458     lua_state->Cblocks[lua_state->numCblocks] = lua_state->Cstack;
00459     lua_state->numCblocks++;
00460 }
00461 
00462 void lua_endblock() {
00463     --lua_state->numCblocks;
00464     lua_state->Cstack = lua_state->Cblocks[lua_state->numCblocks];
00465     luaD_adjusttop(lua_state->Cstack.base);
00466 }
00467 
00468 int32 lua_ref(int32 lock) {
00469     int32 ref;
00470     checkCparams(1);
00471     ref = luaC_ref(lua_state->stack.top - 1, lock);
00472     lua_state->stack.top--;
00473     return ref;
00474 }
00475 
00476 lua_Object lua_getref(int32 r) {
00477     TObject *o = luaC_getref(r);
00478     return (o ? put_luaObject(o) : LUA_NOOBJECT);
00479 }
00480 
00481 
00482 #ifdef LUA_COMPAT2_5
00483 /*
00484 ** API: set a function as a fallback
00485 */
00486 
00487 static void do_unprotectedrun(lua_CFunction f, int32 nParams, int32 nResults) {
00488     StkId base = (lua_state->stack.top - lua_state->stack.stack) - nParams;
00489     luaD_openstack(nParams);
00490     lua_state->stack.stack[base].ttype = LUA_T_CPROTO;
00491     lua_state->stack.stack[base].value.f = f;
00492     lua_state->state_counter1++;
00493     luaD_call(base + 1, nResults);
00494     lua_state->state_counter1--;
00495 }
00496 
00497 lua_Object lua_setfallback(const char *name, lua_CFunction fallback) {
00498     lua_pushstring(name);
00499     lua_pushcfunction(fallback);
00500     do_unprotectedrun(luaT_setfallback, 2, 1);
00501     return put_luaObjectonTop();
00502 }
00503 
00504 #endif
00505 
00506 } // end of namespace Grim
00507 


Generated on Sat Feb 23 2019 05:01:07 for ResidualVM by doxygen 1.7.1
curved edge   curved edge