Browse Source

simpler code for settable and gettable

Roberto Ierusalimschy 25 years ago
parent
commit
b800c38b69
1 changed files with 39 additions and 47 deletions
  1. 39 47
      lvm.c

+ 39 - 47
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.126 2000/08/11 16:17:28 roberto Exp roberto $
+** $Id: lvm.c,v 1.127 2000/08/14 14:05:06 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -115,35 +115,31 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
 ** Receives the table at top-2 and the index at top-1.
 */
 void luaV_gettable (lua_State *L, StkId top) {
-  StkId table = top-2;
-  const TObject *im;
-  if (ttype(table) != TAG_TABLE) {  /* not a table, get gettable TM */
-    im = luaT_getimbyObj(L, table, IM_GETTABLE);
-    if (ttype(im) == TAG_NIL) {
+  StkId t = top-2;
+  int tg;
+  if (ttype(t) == TAG_TABLE &&  /* `t' is a table? */
+      ((tg = hvalue(t)->htag) == TAG_TABLE ||  /* with default tag? */
+        ttype(luaT_getim(L, tg, IM_GETTABLE)) == TAG_NIL)) { /* or no TM? */
+    /* do a primitive get */
+    const TObject *h = luaH_get(L, hvalue(t), t+1);
+    /* result is no nil or there is no `index' tag method? */
+    const TObject *im;
+    if (ttype(h) != TAG_NIL ||
+        (ttype(im=luaT_getim(L, tg, IM_INDEX)) == TAG_NIL))
+      *t = *h;  /* put result into table position */
+    else {  /* call `index' tag method */
       L->top = top;
-      luaG_typeerror(L, table, "index");
+      luaD_callTM(L, im, 2, 1);
     }
   }
-  else {  /* object is a table... */
-    int tg = hvalue(table)->htag;
-    im = luaT_getim(L, tg, IM_GETTABLE);
-    if (ttype(im) == TAG_NIL) {  /* and does not have a `gettable' TM */
-      const TObject *h = luaH_get(L, hvalue(table), table+1);
-      if (ttype(h) == TAG_NIL &&
-          (ttype(im=luaT_getim(L, tg, IM_INDEX)) != TAG_NIL)) {
-        /* result is nil and there is an `index' tag method */
-        L->top = top;
-        luaD_callTM(L, im, 2, 1);  /* calls it */
-      }
-      else
-        *table = *h;  /* `push' result into table position */
-      return;
-    }
-    /* else it has a `gettable' TM, go through to next command */
+  else {  /* try a 'gettable' TM */
+    const TObject *im = luaT_getimbyObj(L, t, IM_GETTABLE);
+    L->top = top;
+    if (ttype(im) != TAG_NIL)  /* call `gettable' tag method */
+      luaD_callTM(L, im, 2, 1);
+    else  /* no tag method */
+      luaG_typeerror(L, t, "index");
   }
-  /* object is not a table, or it has a `gettable' TM */
-  L->top = top;
-  luaD_callTM(L, im, 2, 1);
 }
 
 
@@ -151,30 +147,26 @@ void luaV_gettable (lua_State *L, StkId top) {
 ** Receives table at *t, index at *(t+1) and value at `top'.
 */
 void luaV_settable (lua_State *L, StkId t, StkId top) {
-  const TObject *im;
-  if (ttype(t) != TAG_TABLE) {  /* not a table, get `settable' method */
+  int tg;
+  if (ttype(t) == TAG_TABLE &&  /* `t' is a table? */
+      ((tg = hvalue(t)->htag) == TAG_TABLE ||  /* with default tag? */
+        ttype(luaT_getim(L, tg, IM_SETTABLE)) == TAG_NIL)) /* or no TM? */
+    *luaH_set(L, hvalue(t), t+1) = *(top-1);  /* do a primitive set */
+  else {  /* try a `settable' tag method */
+    const TObject *im = luaT_getimbyObj(L, t, IM_SETTABLE);
     L->top = top;
-    im = luaT_getimbyObj(L, t, IM_SETTABLE);
-    if (ttype(im) == TAG_NIL)
-      luaG_typeerror(L, t, "index");
-  }
-  else {  /* object is a table... */
-    im = luaT_getim(L, hvalue(t)->htag, IM_SETTABLE);
-    if (ttype(im) == TAG_NIL) {  /* and does not have a `settable' method */
-      *luaH_set(L, hvalue(t), t+1) = *(top-1);
-      return;
+    if (ttype(im) != TAG_NIL) {
+      luaD_checkstack(L, 3);
+      *(top+2) = *(top-1);
+      *(top+1) = *(t+1);
+      *(top) = *t;
+      *(top-1) = *im;
+      L->top = top+3;
+      luaD_call(L, top-1, 0);  /* call `settable' tag method */
     }
-    /* else it has a `settable' method, go through to next command */
+    else  /* no tag method... */
+      luaG_typeerror(L, t, "index");
   }
-  /* object is not a table, or it has a `settable' method */
-  /* prepare arguments and call the tag method */
-  luaD_checkstack(L, 3);
-  *(top+2) = *(top-1);
-  *(top+1) = *(t+1);
-  *(top) = *t;
-  *(top-1) = *im;
-  L->top = top+3;
-  luaD_call(L, top-1, 0);
 }