فهرست منبع

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

Roberto Ierusalimschy 23 سال پیش
والد
کامیت
a4c35a3269
3فایلهای تغییر یافته به همراه33 افزوده شده و 19 حذف شده
  1. 1 1
      ldo.c
  2. 8 3
      ltm.c
  3. 24 15
      lvm.c

+ 1 - 1
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 */

+ 8 - 3
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;
   }
 }
 

+ 24 - 15
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: {