Browse Source

cleaner way to ensure alignment for strings and userdata

Roberto Ierusalimschy 24 years ago
parent
commit
8e586c13fc
12 changed files with 92 additions and 103 deletions
  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;
       }