From a4c35a3269f0581da212b3c4abd04989f88425ce Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 10 Dec 2001 20:10:30 -0200 Subject: [PATCH] it doesn't pay to optimize absence when it is an error --- ldo.c | 2 +- ltm.c | 11 ++++++++--- lvm.c | 39 ++++++++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/ldo.c b/ldo.c index aaf4de55..6f7a32f9 100644 --- a/ldo.c +++ b/ldo.c @@ -143,7 +143,7 @@ void luaD_call (lua_State *L, StkId func) { if (ttype(func) != LUA_TFUNCTION) { /* `func' is not a function; check the `function' tag method */ const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); - if (tm == NULL || ttype(tm) != LUA_TFUNCTION) + if (ttype(tm) != LUA_TFUNCTION) luaG_typeerror(L, func, "call"); luaD_openstack(L, func); setobj(func, tm); /* tag method is the new function to be called */ diff --git a/ltm.c b/ltm.c index 5d1c83d1..5e5f1ab2 100644 --- a/ltm.c +++ b/ltm.c @@ -39,6 +39,10 @@ void luaT_init (lua_State *L) { } +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { const TObject *tm = luaH_getstr(events, ename); if (ttype(tm) == LUA_TNIL) { /* no tag method? */ @@ -50,13 +54,14 @@ const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) { + TString *ename = G(L)->tmname[event]; switch (ttype(o)) { case LUA_TTABLE: - return fasttm(L, hvalue(o)->eventtable, event); + return luaH_getstr(hvalue(o)->eventtable, ename); case LUA_TUSERDATA: - return fasttm(L, uvalue(o)->uv.eventtable, event); + return luaH_getstr(uvalue(o)->uv.eventtable, ename); default: - return NULL; + return &luaO_nilobject; } } diff --git a/lvm.c b/lvm.c index ea1ba100..b49d8365 100644 --- a/lvm.c +++ b/lvm.c @@ -113,7 +113,7 @@ static void callTM (lua_State *L, const TObject *f, /* ** Function to index a table. -** Receives the table at `t' and the key at the `key'. +** Receives the table at `t' and the key at `key'. ** leaves the result at `res'. */ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { @@ -132,13 +132,11 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { } /* else will call the tag method */ } else { /* not a table; try a `gettable' tag method */ - if (ttype(t) != LUA_TUSERDATA || - (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_GETTABLE)) == NULL) { + if (ttype(tm = luaT_gettmbyobj(L, t, TM_GETTABLE)) == LUA_TNIL) { luaG_typeerror(L, t, "index"); return; /* to avoid warnings */ } } - lua_assert(tm != NULL); if (ttype(tm) == LUA_TFUNCTION) callTM(L, tm, t, key, NULL, res); else { @@ -163,13 +161,11 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { } /* else will call the tag method */ } else { /* not a table; try a `settable' tag method */ - if (ttype(t) != LUA_TUSERDATA || - (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_SETTABLE)) == NULL) { + if (ttype(tm = luaT_gettmbyobj(L, t, TM_SETTABLE)) == LUA_TNIL) { luaG_typeerror(L, t, "index"); return; /* to avoid warnings */ } } - lua_assert(tm != NULL); if (ttype(tm) == LUA_TFUNCTION) callTM(L, tm, t, key, val, NULL); else { @@ -182,15 +178,10 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, TObject *res, TMS event) { const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ - if (tm == NULL) { + if (ttype(tm) == LUA_TNIL) tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ - if (tm == NULL) { - tm = fasttm(L, hvalue(gt(L)), event); - if (tm == NULL) return 0; /* no tag method */ - } - } if (ttype(tm) != LUA_TFUNCTION) return 0; - callTM(L, tm, p1, p2, NULL, res); + callTM(L, tm, p1, p2, NULL, res); return 1; } @@ -297,6 +288,24 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { } +static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { + const TObject *b = rb; + const TObject *c = rc; + TObject tempb, tempc; + if ((b = luaV_tonumber(b, &tempb)) != NULL && + (c = luaV_tonumber(c, &tempc)) != NULL) { + TObject o, f; + setsvalue(&o, luaS_newliteral(L, "pow")); + luaV_gettable(L, gt(L), &o, &f); + if (ttype(&f) != LUA_TFUNCTION) + luaD_error(L, "`pow' (for `^' operator) is not a function"); + callTM(L, &f, b, c, NULL, ra); + } + else + call_arith(L, rb, rc, ra, TM_POW); +} + + /* ** some macros for common tasks in `luaV_execute' @@ -425,7 +434,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { break; } case OP_POW: { - call_arith(L, RB(i), RKC(i), ra, TM_POW); + powOp(L, ra, RB(i), RKC(i)); break; } case OP_UNM: {