Browse Source

cleaner way to ensure alignment for strings and userdata

Roberto Ierusalimschy 24 năm trước cách đây
mục cha
commit
8e586c13fc
12 tập tin đã thay đổi với 92 bổ sung103 xóa
  1. 7 7
      lapi.c
  2. 3 3
      lcode.c
  3. 3 3
      ldebug.c
  4. 15 15
      lgc.c
  5. 4 4
      llex.c
  6. 23 27
      lobject.h
  7. 18 16
      lstring.c
  8. 3 13
      lstring.h
  9. 2 2
      ltable.c
  10. 3 3
      ltests.c
  11. 3 3
      ltm.c
  12. 8 7
      lvm.c

+ 7 - 7
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.144 2001/06/08 19:00:57 roberto Exp roberto $
+** $Id: lapi.c,v 1.145 2001/06/15 19:16:41 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -244,11 +244,11 @@ LUA_API size_t lua_strlen (lua_State *L, int index) {
   if (o == NULL)
     return 0;
   else if (ttype(o) == LUA_TSTRING)
-    return tsvalue(o)->len;
+    return tsvalue(o)->tsv.len;
   else {
     size_t l;
     lua_lock(L);  /* `luaV_tostring' may create a new string */
-    l = (luaV_tostring(L, o) == 0) ? tsvalue(o)->len : 0;
+    l = (luaV_tostring(L, o) == 0) ? tsvalue(o)->tsv.len : 0;
     lua_unlock(L);
     return l;
   }
@@ -263,7 +263,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
 
 LUA_API void *lua_touserdata (lua_State *L, int index) {
   StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : uvalue(o)->value;
+  return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : uvalue(o)->uv.value;
 }
 
 
@@ -633,7 +633,7 @@ LUA_API void lua_settag (lua_State *L, int tag) {
       hvalue(L->top-1)->htag = tag;
       break;
     case LUA_TUSERDATA:
-      uvalue(L->top-1)->tag = tag;
+      uvalue(L->top-1)->uv.tag = tag;
       break;
     default:
       luaO_verror(L, l_s("cannot change the tag of a %.20s"),
@@ -744,7 +744,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
   void *p;
   lua_lock(L);
   u = pushnewudata(L, size);
-  p = u->value;
+  p = u->uv.value;
   lua_unlock(L);
   return p;
 }
@@ -754,7 +754,7 @@ LUA_API void lua_newuserdatabox (lua_State *L, void *p) {
   Udata *u;
   lua_lock(L);
   u = pushnewudata(L, 0);
-  u->value = p;
+  u->uv.value = p;
   lua_unlock(L);
 }
 

+ 3 - 3
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.74 2001/06/11 14:56:42 roberto Exp roberto $
+** $Id: lcode.c,v 1.75 2001/06/12 14:36:48 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -232,12 +232,12 @@ static int addk (FuncState *fs, TObject *k) {
 
 int luaK_stringk (FuncState *fs, TString *s) {
   Proto *f = fs->f;
-  int c = s->constindex;
+  int c = s->tsv.constindex;
   if (c >= fs->nk || ttype(&f->k[c]) != LUA_TSTRING || tsvalue(&f->k[c]) != s) {
     TObject o;
     setsvalue(&o, s);
     c = addk(fs, &o);
-    s->constindex = (unsigned short)c;  /* hint for next time */
+    s->tsv.constindex = (unsigned short)c;  /* hint for next time */
   }
   return c;
 }

+ 3 - 3
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.81 2001/06/08 19:00:57 roberto Exp roberto $
+** $Id: ldebug.c,v 1.82 2001/06/11 14:56:42 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -483,7 +483,7 @@ static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
     switch (GET_OPCODE(i)) {
       case OP_GETGLOBAL: {
         lua_assert(ttype(&p->k[GETARG_Bc(i)]) == LUA_TSTRING);
-        *name = getstr(tsvalue(&p->k[GETARG_Bc(i)]));
+        *name = svalue(&p->k[GETARG_Bc(i)]);
         return l_s("global");
       }
       case OP_MOVE: {
@@ -497,7 +497,7 @@ static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
       case OP_SELF: {
         int c = GETARG_C(i) - MAXSTACK;
         if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING) {
-          *name = getstr(tsvalue(&p->k[c]));
+          *name = svalue(&p->k[c]);
           return l_s("field");
         }
         break;

+ 15 - 15
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.104 2001/06/13 18:51:20 roberto Exp roberto $
+** $Id: lgc.c,v 1.105 2001/06/15 19:17:33 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -27,7 +27,7 @@ typedef struct GCState {
 
 
 /* mark a string; marks larger than 1 cannot be changed */
-#define strmark(s)    {if ((s)->marked == 0) (s)->marked = 1;}
+#define strmark(s)    {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;}
 
 
 
@@ -184,7 +184,7 @@ static void markall (lua_State *L) {
 static int hasmark (int tt, Value *v) {
   switch (tt) {
     case LUA_TSTRING:
-      return v->ts->marked;
+      return v->ts->tsv.marked;
     case LUA_TUSERDATA:
       return ismarkedudata(v->u);
     case LUA_TTABLE:
@@ -274,12 +274,12 @@ void luaC_collectudata (lua_State *L) {
   while ((curr = *p) != NULL) {
     if (ismarkedudata(curr)) {
       switchudatamark(curr);  /* unmark */
-      p = &curr->next;
+      p = &curr->uv.next;
     }
     else {  /* collect */
-      int tag = curr->tag;
-      *p = curr->next;
-      curr->next = G(L)->TMtable[tag].collected;  /* chain udata */
+      int tag = curr->uv.tag;
+      *p = curr->uv.next;
+      curr->uv.next = G(L)->TMtable[tag].collected;  /* chain udata */
       G(L)->TMtable[tag].collected = curr;
     }
   }
@@ -292,15 +292,15 @@ static void collectstrings (lua_State *L, int all) {
     TString **p = &G(L)->strt.hash[i];
     TString *curr;
     while ((curr = *p) != NULL) {
-      if (curr->marked && !all) {  /* preserve? */
-        if (curr->marked < FIXMARK)  /* does not change FIXMARKs */
-          curr->marked = 0;
-        p = &curr->nexthash;
+      if (curr->tsv.marked && !all) {  /* preserve? */
+        if (curr->tsv.marked < FIXMARK)  /* does not change FIXMARKs */
+          curr->tsv.marked = 0;
+        p = &curr->tsv.nexthash;
       } 
       else {  /* collect */
-        *p = curr->nexthash;
+        *p = curr->tsv.nexthash;
         G(L)->strt.nuse--;
-        luaM_free(L, curr, sizestring(curr->len));
+        luaM_free(L, curr, sizestring(curr->tsv.len));
       }
     }
   }
@@ -344,10 +344,10 @@ void luaC_callgcTMudata (lua_State *L) {
     Udata *udata;
     while ((udata = G(L)->TMtable[tag].collected) != NULL) {
       TObject obj;
-      G(L)->TMtable[tag].collected = udata->next;  /* remove it from list */
+      G(L)->TMtable[tag].collected = udata->uv.next;  /* remove it from list */
       setuvalue(&obj, udata);
       callgcTM(L, &obj);
-      luaM_free(L, udata, sizeudata(udata->len));
+      luaM_free(L, udata, sizeudata(udata->uv.len));
     }
   }
 }

+ 4 - 4
llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 1.85 2001/06/07 15:01:21 roberto Exp roberto $
+** $Id: llex.c,v 1.86 2001/06/13 14:25:49 roberto Exp roberto $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -40,7 +40,7 @@ void luaX_init (lua_State *L) {
   for (i=0; i<NUM_RESERVED; i++) {
     TString *ts = luaS_new(L, token2string[i]);
     lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN);
-    ts->marked = (unsigned short)(RESERVEDMARK+i);  /* reserved word */
+    ts->tsv.marked = (unsigned short)(RESERVEDMARK+i);  /* reserved word */
   }
 }
 
@@ -370,8 +370,8 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) {
           /* identifier or reserved word */
           size_t l = readname(LS);
           TString *ts = luaS_newlstr(LS->L, (l_char *)G(LS->L)->Mbuffer, l);
-          if (ts->marked >= RESERVEDMARK)  /* reserved word? */
-            return ts->marked-RESERVEDMARK+FIRST_RESERVED;
+          if (ts->tsv.marked >= RESERVEDMARK)  /* reserved word? */
+            return ts->tsv.marked-RESERVEDMARK+FIRST_RESERVED;
           seminfo->ts = ts;
           return TK_NAME;
         }

+ 23 - 27
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 1.104 2001/06/06 18:00:19 roberto Exp roberto $
+** $Id: lobject.h,v 1.105 2001/06/07 15:01:21 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -28,8 +28,8 @@
 
 
 typedef union {
-  struct TString *ts;
-  struct Udata *u;
+  union TString *ts;
+  union Udata *u;
   struct Closure *cl;
   struct Hash *h;
   lua_Number n;		/* LUA_TNUMBER */
@@ -80,40 +80,36 @@ typedef TObject *StkId;  /* index to stack elements */
 /*
 ** String headers for string table
 */
-typedef struct TString {
-  lu_hash hash;
-  size_t len;
-  unsigned short constindex;  /* hint to reuse constants */
-  short marked;
-  struct TString *nexthash;  /* chain for hash table */
-} TString;
-
-
-
-/*
-** type equivalent to TString, but with maximum alignment requirements
-*/
-union L_UTString {
-  TString ts;
+typedef union TString {
   union L_Umaxalign dummy;  /* ensures maximum alignment for strings */
-};
+  struct {
+    lu_hash hash;
+    size_t len;
+    unsigned short constindex;  /* hint to reuse constants */
+    short marked;
+    union TString *nexthash;  /* chain for hash table */
+  } tsv;
+} TString;
 
 
-#define getstr(ts)	((l_char *)((union L_UTString *)(ts) + 1))
+#define getstr(ts)	((l_char *)((ts) + 1))
 #define svalue(o)       getstr(tsvalue(o))
 
 
 
-typedef struct Udata {
-  int tag;  /* negative means `marked' (only during GC) */
-  void *value;
-  size_t len;
-  struct Udata *next;  /* chain for list of all udata */
+typedef union Udata {
+  union L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
+  struct {
+    int tag;  /* negative means `marked' (only during GC) */
+    void *value;
+    size_t len;
+    union Udata *next;  /* chain for list of all udata */
+  } uv;
 } Udata;
 
 
-#define switchudatamark(u)	((u)->tag = (-((u)->tag+1)))
-#define ismarkedudata(u)	((u)->tag < 0)
+#define switchudatamark(u)	((u)->uv.tag = (-((u)->uv.tag+1)))
+#define ismarkedudata(u)	((u)->uv.tag < 0)
 
 
 

+ 18 - 16
lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 1.63 2001/06/06 18:00:19 roberto Exp roberto $
+** $Id: lstring.c,v 1.64 2001/06/07 15:01:21 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -32,11 +32,11 @@ void luaS_resize (lua_State *L, int newsize) {
   for (i=0; i<tb->size; i++) {
     TString *p = tb->hash[i];
     while (p) {  /* for each node in the list */
-      TString *next = p->nexthash;  /* save next */
-      lu_hash h = p->hash;
+      TString *next = p->tsv.nexthash;  /* save next */
+      lu_hash h = p->tsv.hash;
       int h1 = lmod(h, newsize);  /* new position */
       lua_assert((int)(h%newsize) == lmod(h, newsize));
-      p->nexthash = newhash[h1];  /* chain it in new position */
+      p->tsv.nexthash = newhash[h1];  /* chain it in new position */
       newhash[h1] = p;
       p = next;
     }
@@ -50,16 +50,16 @@ void luaS_resize (lua_State *L, int newsize) {
 static TString *newlstr (lua_State *L, const l_char *str, size_t l, lu_hash h) {
   TString *ts = (TString *)luaM_malloc(L, sizestring(l));
   stringtable *tb;
-  ts->nexthash = NULL;
-  ts->len = l;
-  ts->hash = h;
-  ts->marked = 0;
-  ts->constindex = 0;
+  ts->tsv.nexthash = NULL;
+  ts->tsv.len = l;
+  ts->tsv.hash = h;
+  ts->tsv.marked = 0;
+  ts->tsv.constindex = 0;
   memcpy(getstr(ts), str, l*sizeof(l_char));
   getstr(ts)[l] = l_c('\0');  /* ending 0 */
   tb = &G(L)->strt;
   h = lmod(h, tb->size);
-  ts->nexthash = tb->hash[h];  /* chain new entry */
+  ts->tsv.nexthash = tb->hash[h];  /* chain new entry */
   tb->hash[h] = ts;
   tb->nuse++;
   if (tb->nuse > (ls_nstr)tb->size && tb->size <= MAX_INT/2)
@@ -75,8 +75,10 @@ TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) {
   size_t l1;
   for (l1=l; l1>=step; l1-=step)  /* compute hash */
     h = h ^ ((h<<5)+(h>>2)+uchar(str[l1-1]));
-  for (ts = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; ts; ts = ts->nexthash) {
-    if (ts->len == l && (memcmp(str, getstr(ts), l) == 0))
+  for (ts = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
+       ts != NULL;
+       ts = ts->tsv.nexthash) {
+    if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))
       return ts;
   }
   return newlstr(L, str, l, h);  /* not found */
@@ -85,11 +87,11 @@ TString *luaS_newlstr (lua_State *L, const l_char *str, size_t l) {
 
 Udata *luaS_newudata (lua_State *L, size_t s) {
   Udata *u = (Udata *)luaM_malloc(L, sizeudata(s));
-  u->len = s;
-  u->tag = 0;
-  u->value = ((union L_UUdata *)(u) + 1);
+  u->uv.len = s;
+  u->uv.tag = 0;
+  u->uv.value = u + 1;
   /* chain it on udata list */
-  u->next = G(L)->rootudata;
+  u->uv.next = G(L)->rootudata;
   G(L)->rootudata = u;
   return u;
 }

+ 3 - 13
lstring.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.h,v 1.31 2001/02/23 17:17:25 roberto Exp roberto $
+** $Id: lstring.h,v 1.32 2001/06/06 18:00:19 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -13,16 +13,6 @@
 
 
 
-/*
-** type equivalent to Udata, but with maximum alignment requirements
-*/
-union L_UUdata {
-  Udata u;
-  union L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
-};
-
-
-
 /*
 ** any TString with mark>=FIXMARK is never collected.
 ** Marks>=RESERVEDMARK are used to identify reserved words.
@@ -31,10 +21,10 @@ union L_UUdata {
 #define RESERVEDMARK	3
 
 
-#define sizestring(l)	((lu_mem)sizeof(union L_UTString)+ \
+#define sizestring(l)	((lu_mem)sizeof(union TString)+ \
                          ((lu_mem)(l)+1)*sizeof(l_char))
 
-#define sizeudata(l)	((lu_mem)sizeof(union L_UUdata)+(l))
+#define sizeudata(l)	((lu_mem)sizeof(union Udata)+(l))
 
 #define luaS_new(L, s)	(luaS_newlstr(L, s, strlen(s)))
 #define luaS_newliteral(L, s)	(luaS_newlstr(L, l_s("") s, \

+ 2 - 2
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.79 2001/04/11 14:42:41 roberto Exp roberto $
+** $Id: ltable.c,v 1.80 2001/06/06 18:00:19 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -33,7 +33,7 @@
 
 
 #define hashnum(t,n)		(&t->node[lmod((lu_hash)(ls_hash)(n), t->size)])
-#define hashstr(t,str)		(&t->node[lmod((str)->hash, t->size)])
+#define hashstr(t,str)		(&t->node[lmod((str)->tsv.hash, t->size)])
 #define hashpointer(t,p)	(&t->node[lmod(IntPoint(p), t->size)])
 
 

+ 3 - 3
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 1.81 2001/06/05 18:17:01 roberto Exp roberto $
+** $Id: ltests.c,v 1.82 2001/06/06 18:00:19 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -290,7 +290,7 @@ static int mem_query (lua_State *L) {
 static int hash_query (lua_State *L) {
   if (lua_isnull(L, 2)) {
     luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, l_s("string expected"));
-    lua_pushnumber(L, tsvalue(luaA_index(L, 1))->hash);
+    lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash);
   }
   else {
     Hash *t;
@@ -349,7 +349,7 @@ static int string_query (lua_State *L) {
   else if (s < tb->size) {
     TString *ts;
     int n = 0;
-    for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
+    for (ts = tb->hash[s]; ts; ts = ts->tsv.nexthash) {
       setsvalue(L->top, ts);
       incr_top;
       n++;

+ 3 - 3
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 1.71 2001/03/26 14:31:49 roberto Exp roberto $
+** $Id: ltm.c,v 1.72 2001/06/06 18:00:19 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -127,7 +127,7 @@ LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
 int luaT_tag (const TObject *o) {
   int t = ttype(o);
   switch (t) {
-    case LUA_TUSERDATA: return uvalue(o)->tag;
+    case LUA_TUSERDATA: return uvalue(o)->uv.tag;
     case LUA_TTABLE:    return hvalue(o)->htag;
     default:            return t;
   }
@@ -140,7 +140,7 @@ const l_char *luaT_typename (global_State *G, const TObject *o) {
   TString *ts;
   switch (t) {
     case LUA_TUSERDATA:
-      tag = uvalue(o)->tag;
+      tag = uvalue(o)->uv.tag;
       break;
     case LUA_TTABLE:
       tag = hvalue(o)->htag;

+ 8 - 7
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.184 2001/06/11 14:56:42 roberto Exp roberto $
+** $Id: lvm.c,v 1.185 2001/06/15 19:17:17 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -249,9 +249,9 @@ static void call_arith (lua_State *L, StkId p1, TObject *p2,
 
 static int luaV_strlessthan (const TString *ls, const TString *rs) {
   const l_char *l = getstr(ls);
-  size_t ll = ls->len;
+  size_t ll = ls->tsv.len;
   const l_char *r = getstr(rs);
-  size_t lr = rs->len;
+  size_t lr = rs->tsv.len;
   for (;;) {
     int temp = strcoll(l, r);
     if (temp != 0) return (temp < 0);
@@ -289,20 +289,21 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
     if (tostring(L, top-2) || tostring(L, top-1)) {
       if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
         luaG_concaterror(L, top-2, top-1);
-    } else if (tsvalue(top-1)->len > 0) {  /* if len=0, do nothing */
+    } else if (tsvalue(top-1)->tsv.len > 0) {  /* if len=0, do nothing */
       /* at least two string values; get as many as possible */
-      lu_mem tl = (lu_mem)tsvalue(top-1)->len + (lu_mem)tsvalue(top-2)->len;
+      lu_mem tl = (lu_mem)tsvalue(top-1)->tsv.len +
+                  (lu_mem)tsvalue(top-2)->tsv.len;
       l_char *buffer;
       int i;
       while (n < total && !tostring(L, top-n-1)) {  /* collect total length */
-        tl += tsvalue(top-n-1)->len;
+        tl += tsvalue(top-n-1)->tsv.len;
         n++;
       }
       if (tl > MAX_SIZET) luaD_error(L, l_s("string size overflow"));
       buffer = luaO_openspace(L, tl, l_char);
       tl = 0;
       for (i=n; i>0; i--) {  /* concat all strings */
-        size_t l = tsvalue(top-i)->len;
+        size_t l = tsvalue(top-i)->tsv.len;
         memcpy(buffer+tl, svalue(top-i), l);
         tl += l;
       }