/* ** Function to index a table. ** Receives the table at `t' and the key at top. */ const TObject *luaV_gettable (lua_State *L, StkId t) { Closure *tm; int tg; if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */ /* do a primitive get */ const TObject *h = luaH_get(L, hvalue(t), L->top-1); /* result is no nil or there is no `index' tag method? */ if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL)) return h; /* return result */ /* else call `index' tag method */ } else { /* try a `gettable' tag method */ tm = luaT_gettmbyObj(L, t, TM_GETTABLE); } if (tm != NULL) { /* is there a tag method? */ luaD_checkstack(L, 2); *(L->top+1) = *(L->top-1); /* key */ *L->top = *t; /* table */ clvalue(L->top-1) = tm; /* tag method */ ttype(L->top-1) = LUA_TFUNCTION; L->top += 2; luaD_call(L, L->top - 3, 1); return L->top - 1; /* call result */ } else { /* no tag method */ luaG_typeerror(L, t, "index"); return NULL; /* to avoid warnings */ } }
static void marktagmethods (lua_State *L, GCState *st) { int e; for (e=0; e<TM_N; e++) { int t; for (t=0; t<=L->last_tag; t++) { Closure *cl = luaT_gettm(L, t, e); if (cl) markclosure(st, cl); } } }
static const char *travtagmethods (lua_State *L, const TObject *o) { if (ttype(o) == LUA_TFUNCTION) { int e; for (e=0; e<TM_N; e++) { int t; for (t=0; t<=L->last_tag; t++) if (clvalue(o) == luaT_gettm(L, t, e)) return luaT_eventname[e]; } } return NULL; }
static int call_binTM (lua_State *L, StkId top, TMS event) { /* try first operand */ Closure *tm = luaT_gettmbyObj(L, top-2, event); L->top = top; if (tm == NULL) { tm = luaT_gettmbyObj(L, top-1, event); /* try second operand */ if (tm == NULL) { tm = luaT_gettm(L, 0, event); /* try a `global' method */ if (tm == NULL) return 0; /* error */ } } lua_pushstring(L, luaT_eventname[event]); luaD_callTM(L, tm, 3, 1); return 1; }
/* ** Receives table at `t', key at `key' and value at top. */ void luaV_settable (lua_State *L, StkId t, StkId key) { int tg; if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */ *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ else { /* try a `settable' tag method */ Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE); if (tm != NULL) { luaD_checkstack(L, 3); *(L->top+2) = *(L->top-1); *(L->top+1) = *key; *(L->top) = *t; clvalue(L->top-1) = tm; ttype(L->top-1) = LUA_TFUNCTION; L->top += 3; luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ } else /* no tag method... */ luaG_typeerror(L, t, "index"); } }
static void init_entry (lua_State *L, int tag) { int i; for (i=0; i<TM_N; i++) luaT_gettm(L, tag, i) = NULL; L->TMtable[tag].collected = NULL; }