it doesn't pay to optimize absence when it is an error

This commit is contained in:
Roberto Ierusalimschy 2001-12-10 20:10:30 -02:00
parent 9cd36059ad
commit a4c35a3269
3 changed files with 33 additions and 19 deletions

2
ldo.c
View File

@ -143,7 +143,7 @@ void luaD_call (lua_State *L, StkId func) {
if (ttype(func) != LUA_TFUNCTION) { if (ttype(func) != LUA_TFUNCTION) {
/* `func' is not a function; check the `function' tag method */ /* `func' is not a function; check the `function' tag method */
const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); 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"); luaG_typeerror(L, func, "call");
luaD_openstack(L, func); luaD_openstack(L, func);
setobj(func, tm); /* tag method is the new function to be called */ setobj(func, tm); /* tag method is the new function to be called */

11
ltm.c
View File

@ -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 *luaT_gettm (Table *events, TMS event, TString *ename) {
const TObject *tm = luaH_getstr(events, ename); const TObject *tm = luaH_getstr(events, ename);
if (ttype(tm) == LUA_TNIL) { /* no tag method? */ 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) { const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
TString *ename = G(L)->tmname[event];
switch (ttype(o)) { switch (ttype(o)) {
case LUA_TTABLE: case LUA_TTABLE:
return fasttm(L, hvalue(o)->eventtable, event); return luaH_getstr(hvalue(o)->eventtable, ename);
case LUA_TUSERDATA: case LUA_TUSERDATA:
return fasttm(L, uvalue(o)->uv.eventtable, event); return luaH_getstr(uvalue(o)->uv.eventtable, ename);
default: default:
return NULL; return &luaO_nilobject;
} }
} }

37
lvm.c
View File

@ -113,7 +113,7 @@ static void callTM (lua_State *L, const TObject *f,
/* /*
** Function to index a table. ** 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'. ** leaves the result at `res'.
*/ */
void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId 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 will call the tag method */
} else { /* not a table; try a `gettable' tag method */ } else { /* not a table; try a `gettable' tag method */
if (ttype(t) != LUA_TUSERDATA || if (ttype(tm = luaT_gettmbyobj(L, t, TM_GETTABLE)) == LUA_TNIL) {
(tm = fasttm(L, uvalue(t)->uv.eventtable, TM_GETTABLE)) == NULL) {
luaG_typeerror(L, t, "index"); luaG_typeerror(L, t, "index");
return; /* to avoid warnings */ return; /* to avoid warnings */
} }
} }
lua_assert(tm != NULL);
if (ttype(tm) == LUA_TFUNCTION) if (ttype(tm) == LUA_TFUNCTION)
callTM(L, tm, t, key, NULL, res); callTM(L, tm, t, key, NULL, res);
else { else {
@ -163,13 +161,11 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
} }
/* else will call the tag method */ /* else will call the tag method */
} else { /* not a table; try a `settable' tag method */ } else { /* not a table; try a `settable' tag method */
if (ttype(t) != LUA_TUSERDATA || if (ttype(tm = luaT_gettmbyobj(L, t, TM_SETTABLE)) == LUA_TNIL) {
(tm = fasttm(L, uvalue(t)->uv.eventtable, TM_SETTABLE)) == NULL) {
luaG_typeerror(L, t, "index"); luaG_typeerror(L, t, "index");
return; /* to avoid warnings */ return; /* to avoid warnings */
} }
} }
lua_assert(tm != NULL);
if (ttype(tm) == LUA_TFUNCTION) if (ttype(tm) == LUA_TFUNCTION)
callTM(L, tm, t, key, val, NULL); callTM(L, tm, t, key, val, NULL);
else { else {
@ -182,13 +178,8 @@ 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, static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
TObject *res, TMS event) { TObject *res, TMS event) {
const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 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 */ 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; if (ttype(tm) != LUA_TFUNCTION) return 0;
callTM(L, tm, p1, p2, NULL, res); callTM(L, tm, p1, p2, NULL, res);
return 1; 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' ** some macros for common tasks in `luaV_execute'
@ -425,7 +434,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
break; break;
} }
case OP_POW: { case OP_POW: {
call_arith(L, RB(i), RKC(i), ra, TM_POW); powOp(L, ra, RB(i), RKC(i));
break; break;
} }
case OP_UNM: { case OP_UNM: {