/* ** Function to index a table. ** Receives the table at top-2 and the index at top-1. */ void luaV_gettable (void) { struct Stack *S = &L->stack; TObject *im; if (ttype(S->top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */ im = luaT_getimbyObj(S->top-2, IM_GETTABLE); else { /* object is a table... */ int32 tg = (S->top-2)->value.a->htag; im = luaT_getim(tg, IM_GETTABLE); if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */ TObject *h = luaH_get(avalue(S->top-2), S->top-1); if (h != NULL && ttype(h) != LUA_T_NIL) { --S->top; *(S->top-1) = *h; } else if (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL) luaD_callTM(im, 2, 1); else { --S->top; ttype(S->top-1) = LUA_T_NIL; } return; } /* else it has a "gettable" method, go through to next command */ } /* object is not a table, or it has a "gettable" method */ if (ttype(im) != LUA_T_NIL) luaD_callTM(im, 2, 1); else lua_error("indexed expression not a table"); }
void luaT_setfallback() { static const char *oldnames [] = { "error", "getglobal", "arith", "order", NULL }; TObject oldfunc; lua_CFunction replace; if (!tmFBAdded) { luaL_addlibtolist(tmFB, (sizeof(tmFB) / sizeof(tmFB[0]))); tmFBAdded = true; } const char *name = luaL_check_string(1); lua_Object func = lua_getparam(2); luaL_arg_check(lua_isfunction(func), 2, "function expected"); switch (luaO_findstring(name, oldnames)) { case 0: // old error fallback oldfunc = errorim; errorim = *luaA_Address(func); replace = errorFB; break; case 1: // old getglobal fallback oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); replace = nilFB; break; case 2: { // old arith fallback int32 i; oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW); for (i = IM_ADD; i <= IM_UNM; i++) // ORDER IM fillvalids(i, luaA_Address(func)); replace = typeFB; break; } case 3: { // old order fallback int32 i; oldfunc = *luaT_getim(LUA_T_NIL, IM_LT); for (i = IM_LT; i <= IM_GE; i++) // ORDER IM fillvalids(i, luaA_Address(func)); replace = typeFB; break; } default: { int32 e; if ((e = luaO_findstring(name, luaT_eventname)) >= 0) { oldfunc = *luaT_getim(LUA_T_NIL, e); fillvalids(e, luaA_Address(func)); replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; } else { luaL_verror("`%.50s' is not a valid fallback name", name); replace = NULL; // to avoid warnings oldfunc.ttype = LUA_T_NIL; // to avoid warnings } } } if (oldfunc.ttype != LUA_T_NIL) luaA_pushobject(&oldfunc); else lua_pushcfunction(replace); }
int32 lua_copytagmethods(int32 tagto, int32 tagfrom) { int32 e; checktag(tagto); checktag(tagfrom); for (e = 0; e < IM_N; e++) { if (validevent(tagto, e)) *luaT_getim(tagto, e) = *luaT_getim(tagfrom, e); } return tagto; }
void luaT_settagmethod(int32 t, const char *event, TObject *func) { TObject temp = *func; int32 e = luaI_checkevent(event, luaT_eventname); checktag(t); if (!validevent(t, e)) luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d", luaT_eventname[e], t); *func = *luaT_getim(t,e); *luaT_getim(t, e) = temp; }
int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) { int e; checktag(L, tagto); checktag(L, tagfrom); for (e=0; e<IM_N; e++) { if (luaT_validevent(tagto, e)) *luaT_getim(L, tagto, e) = *luaT_getim(L, tagfrom, e); } return tagto; }
void luaT_setfallback (void) { static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; TObject oldfunc; lua_CFunction replace; char *name = luaL_check_string(1); lua_Object func = lua_getparam(2); luaL_arg_check(lua_isfunction(func), 2, "function expected"); switch (luaL_findstring(name, oldnames)) { case 0: /* old error fallback */ oldfunc = L->errorim; L->errorim = *luaA_Address(func); replace = errorFB; break; case 1: /* old getglobal fallback */ oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); replace = nilFB; break; case 2: { /* old arith fallback */ int i; oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW); for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ fillvalids(i, luaA_Address(func)); replace = typeFB; break; } case 3: { /* old order fallback */ int i; oldfunc = *luaT_getim(LUA_T_NIL, IM_LT); for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ fillvalids(i, luaA_Address(func)); replace = typeFB; break; } default: { int e; if ((e = luaL_findstring(name, luaT_eventname)) >= 0) { oldfunc = *luaT_getim(LUA_T_NIL, e); fillvalids(e, luaA_Address(func)); replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; } else { luaL_verror("`%.50s' is not a valid fallback name", name); replace = NULL; /* to avoid warnings */ } } } if (oldfunc.ttype != LUA_T_NIL) luaA_pushobject(&oldfunc); else lua_pushcfunction(replace); }
void luaT_settagmethod (lua_State *L, int t, const char *event, TObject *func) { TObject temp; int e; e = luaI_checkevent(L, event, t); checktag(L, t); if (!luaT_validevent(t, e)) luaL_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s", luaT_eventname[e], luaO_typenames[t], (t == TAG_TABLE || t == TAG_USERDATA) ? " with default tag" : ""); temp = *func; *func = *luaT_getim(L, t,e); *luaT_getim(L, t, e) = temp; }
static void fillvalids (IMS e, TObject *func) { int t; for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++) if (validevent(t, e)) *luaT_getim(t, e) = *func; }
TObject *luaT_gettagmethod(int32 t, const char *event) { int32 e = luaI_checkevent(event, luaT_eventname); checktag(t); if (validevent(t, e)) return luaT_getim(t,e); else return &luaO_nilobject; }
const TObject *luaT_gettagmethod (lua_State *L, int t, const char *event) { int e; e = luaI_checkevent(L, event, t); checktag(L, t); if (luaT_validevent(t, e)) return luaT_getim(L, t,e); else return &luaO_nilobject; }
const char *luaT_travtagmethods (lua_State *L, int (*fn)(lua_State *, TObject *)) { /* ORDER IM */ int e; for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { int t; for (t=0; t<=L->last_tag; t++) if (fn(L, luaT_getim(L, t,e))) return luaT_eventname[e]; } return NULL; }
const char *luaT_travtagmethods(int32 (*fn)(TObject *)) { int32 e; if (fn(&errorim)) return "error"; for (e = IM_GETTABLE; e <= IM_FUNCTION; e++) { // ORDER IM int32 t; for (t = 0; t >= last_tag; t--) if (fn(luaT_getim(t, e))) return luaT_eventname[e]; } return NULL; }
char *luaT_travtagmethods (int (*fn)(TObject *)) { int e; if (fn(&L->errorim)) return "error"; for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */ int t; for (t=0; t>=L->last_tag; t--) if (fn(luaT_getim(t,e))) return luaT_eventname[e]; } return NULL; }
static void call_binTM(IMS event, const char *msg) { TObject *im = luaT_getimbyObj(lua_state->stack.top - 2, event); // try first operand if (ttype(im) == LUA_T_NIL) { im = luaT_getimbyObj(lua_state->stack.top - 1, event); // try second operand if (ttype(im) == LUA_T_NIL) { im = luaT_getim(0, event); // try a 'global' i.m. if (ttype(im) == LUA_T_NIL) lua_error(msg); } } lua_pushstring(luaT_eventname[event]); luaD_callTM(im, 3, 1); }
static void init_entry (int tag) { int i; for (i=0; i<IM_N; i++) ttype(luaT_getim(tag, i)) = LUA_T_NIL; }
static void init_entry (lua_State *L, int tag) { int i; for (i=0; i<IM_N; i++) ttype(luaT_getim(L, tag, i)) = TAG_NIL; }