Browse Source

clearer way to set tables.

Roberto Ierusalimschy 26 năm trước cách đây
mục cha
commit
fb1cf6ab2d
5 tập tin đã thay đổi với 46 bổ sung45 xóa
  1. 3 2
      lapi.c
  2. 3 3
      lopcodes.h
  3. 3 3
      lparser.c
  4. 35 35
      lvm.c
  5. 2 2
      lvm.h

+ 3 - 2
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.33 1999/02/03 16:42:42 roberto Exp roberto $
+** $Id: lapi.c,v 1.34 1999/02/04 17:47:59 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -181,7 +181,8 @@ lua_Object lua_rawgettable (void)
 
 void lua_settable (void) {
   checkCparams(3);
-  luaV_settable(L->stack.top-3, 0);
+  luaV_settable(L->stack.top-3);
+  L->stack.top -= 2;  /* pop table and index */
 }
 
 

+ 3 - 3
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.20 1999/02/02 19:41:17 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.21 1999/02/04 16:36:16 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -55,8 +55,8 @@ SETGLOBAL,/*	b	x		-		VAR[CNST[b]]=x  */
 SETGLOBALDUPW,/*w	x		x		VAR[CNST[w]]=x  */
 SETGLOBALDUP,/*	b	x		x		VAR[CNST[b]]=x  */
 
-SETTABLE0,/*	-	v i t		-		t[i]=v  */
-SETTABLEDUP,/*	-	v i t		v		t[i]=v  */
+SETTABLEPOP,/*	-	v i t		-		t[i]=v  */
+SETTABPPDUP,/*	-	v i t		v		t[i]=v  */
 
 SETTABLE,/*	b	v a_b...a_1 i t	a_b...a_1 i t	t[i]=v  */
 

+ 3 - 3
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.15 1999/02/04 16:36:16 roberto Exp roberto $
+** $Id: lparser.c,v 1.16 1999/02/04 17:47:59 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -490,7 +490,7 @@ static void genstorevar (LexState *ls, vardesc *var, OpCode *codes) {
 
 
 static void storevar (LexState *ls, vardesc *var) {
-  static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLE0};
+  static OpCode codes[] = {SETLOCAL, SETGLOBAL, SETTABLEPOP};
   genstorevar(ls, var, codes);
 }
 
@@ -954,7 +954,7 @@ static void exp0 (LexState *ls, vardesc *v) {
 
 static void Gexp (LexState *ls, vardesc *v) {
   /* Gexp -> exp0 | var '=' exp1 */
-  static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEDUP};
+  static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABPPDUP};
   exp0(ls, v);
   if (v->k != VEXP && optional(ls, '=')) {  /* assignment expression? */
     unloaddot(ls, v);

+ 35 - 35
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.44 1999/02/04 16:36:16 roberto Exp roberto $
+** $Id: lvm.c,v 1.45 1999/02/04 17:47:59 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -110,64 +110,62 @@ void luaV_closure (int nelems) {
 ** Receives the table at top-2 and the index at top-1.
 */
 void luaV_gettable (void) {
-  struct Stack *S = &L->stack;
+  TObject *table = L->stack.top-2;
   TObject *im;
-  if (ttype(S->top-2) != LUA_T_ARRAY)  /* not a table, get "gettable" method */
-    im = luaT_getimbyObj(S->top-2, IM_GETTABLE);
+  if (ttype(table) != LUA_T_ARRAY) {  /* not a table, get gettable method */
+    im = luaT_getimbyObj(table, IM_GETTABLE);
+    if (ttype(im) == LUA_T_NIL)
+      lua_error("indexed expression not a table");
+  }
   else {  /* object is a table... */
-    int tg = (S->top-2)->value.a->htag;
+    int tg = table->value.a->htag;
     im = luaT_getim(tg, IM_GETTABLE);
     if (ttype(im) == LUA_T_NIL) {  /* and does not have a "gettable" method */
-      TObject *h = luaH_get(avalue(S->top-2), S->top-1);
-      if (ttype(h) != LUA_T_NIL) {
-        --S->top;
-        *(S->top-1) = *h;
+      TObject *h = luaH_get(avalue(table), table+1);
+      if (ttype(h) == LUA_T_NIL &&
+          (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)) {
+        /* result is nil and there is an "index" tag method */
+        luaD_callTM(im, 2, 1);  /* calls it */
       }
-      else if (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL)
-        luaD_callTM(im, 2, 1);
       else {
-        --S->top;
-        ttype(S->top-1) = LUA_T_NIL;
+        L->stack.top--;
+        *table = *h;  /* "push" result into table position */
       }
       return;
     }
     /* else it has a "gettable" method, go through to next command */
   }
   /* object is not a table, or it has a "gettable" method */
-  if (ttype(im) == LUA_T_NIL)
-    lua_error("indexed expression not a table");
   luaD_callTM(im, 2, 1);
 }
 
 
 /*
-** Function to store indexed based on values at the stack.top
-** deep = 1: "deep L->stack.stack" store (with tag methods)
+** Receives table at *t, index at *(t+1) and value at top.
 */
-void luaV_settable (TObject *t, int deep) {
+void luaV_settable (TObject *t) {
   struct Stack *S = &L->stack;
   TObject *im;
-  if (ttype(t) != LUA_T_ARRAY)  /* not a table, get "settable" method */
+  if (ttype(t) != LUA_T_ARRAY) {  /* not a table, get "settable" method */
     im = luaT_getimbyObj(t, IM_SETTABLE);
+    if (ttype(im) == LUA_T_NIL)
+      lua_error("indexed expression not a table");
+  }
   else {  /* object is a table... */
     im = luaT_getim(avalue(t)->htag, IM_SETTABLE);
     if (ttype(im) == LUA_T_NIL) {  /* and does not have a "settable" method */
       luaH_set(avalue(t), t+1, S->top-1);
-      /* if deep, pop only value; otherwise, pop table, index and value */
-      S->top -= (deep) ? 1 : 3;
+      S->top--;  /* pop value */
       return;
     }
     /* else it has a "settable" method, go through to next command */
   }
   /* object is not a table, or it has a "settable" method */
-  if (ttype(im) == LUA_T_NIL)
-    lua_error("indexed expression not a table");
-  if (deep) {  /* table and index were not on top; copy them */
-    *(S->top+1) = *(L->stack.top-1);
-    *(S->top) = *(t+1);
-    *(S->top-1) = *t;
-    S->top += 2;  /* WARNING: caller must assure stack space */
-  }
+  /* prepare arguments and call the tag method */
+  *(S->top+1) = *(L->stack.top-1);
+  *(S->top) = *(t+1);
+  *(S->top-1) = *t;
+  S->top += 2;  /* WARNING: caller must assure stack space */
   luaD_callTM(im, 3, 0);
 }
 
@@ -421,19 +419,21 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
         luaV_setglobal(tsvalue(&consts[aux]));
         break;
 
-      case SETTABLE0:
-       luaV_settable(S->top-3, 0);
+      case SETTABLEPOP:
+       luaV_settable(S->top-3);
+       S->top -= 2;  /* pop table and index */
        break;
 
-      case SETTABLEDUP: {
+      case SETTABPPDUP: {
        TObject temp = *(S->top-1);
-       luaV_settable(S->top-3, 0);
-       *(S->top++) = temp;
+       luaV_settable(S->top-3);
+       S->top--;  /* pop index (temp goes into "table" position) */
+       *(S->top-1) = temp;
        break;
      }
 
       case SETTABLE:
-        luaV_settable(S->top-3-(*pc++), 1);
+        luaV_settable(S->top-3-(*pc++));
         break;
 
       case SETLISTW: aux += highbyte(*pc++);

+ 2 - 2
lvm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.h,v 1.6 1998/12/30 13:16:50 roberto Exp roberto $
+** $Id: lvm.h,v 1.7 1998/12/30 17:26:49 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -22,7 +22,7 @@ int luaV_tonumber (TObject *obj);
 int luaV_tostring (TObject *obj);
 void luaV_setn (Hash *t, int val);
 void luaV_gettable (void);
-void luaV_settable (TObject *t, int deep);
+void luaV_settable (TObject *t);
 void luaV_rawsettable (TObject *t);
 void luaV_getglobal (TaggedString *ts);
 void luaV_setglobal (TaggedString *ts);