From 8e586c13fcf3066886a7edd69011304eaad57a2b Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 15 Jun 2001 17:36:57 -0300 Subject: [PATCH] cleaner way to ensure alignment for strings and userdata --- lapi.c | 14 +++++++------- lcode.c | 6 +++--- ldebug.c | 6 +++--- lgc.c | 30 +++++++++++++++--------------- llex.c | 8 ++++---- lobject.h | 50 +++++++++++++++++++++++--------------------------- lstring.c | 34 ++++++++++++++++++---------------- lstring.h | 16 +++------------- ltable.c | 4 ++-- ltests.c | 6 +++--- ltm.c | 6 +++--- lvm.c | 15 ++++++++------- 12 files changed, 92 insertions(+), 103 deletions(-) diff --git a/lapi.c b/lapi.c index effcc2aaf..31f11702f 100644 --- a/lapi.c +++ b/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); } diff --git a/lcode.c b/lcode.c index 5413058eb..84052abf2 100644 --- a/lcode.c +++ b/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; } diff --git a/ldebug.c b/ldebug.c index 27494a4e0..a0293b10d 100644 --- a/ldebug.c +++ b/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; diff --git a/lgc.c b/lgc.c index baaca9a73..de5998e31 100644 --- a/lgc.c +++ b/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)); } } } diff --git a/llex.c b/llex.c index bb50c276f..c921b1b4a 100644 --- a/llex.c +++ b/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; imarked = (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; } diff --git a/lobject.h b/lobject.h index 53df58cc5..2f363ec75 100644 --- a/lobject.h +++ b/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) diff --git a/lstring.c b/lstring.c index 21cad45bb..a71142bb9 100644 --- a/lstring.c +++ b/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; isize; 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; } diff --git a/lstring.h b/lstring.h index 130b3a81d..02cbc1abc 100644 --- a/lstring.h +++ b/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, \ diff --git a/ltable.c b/ltable.c index c4a2c7899..4a20bb23c 100644 --- a/ltable.c +++ b/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)]) diff --git a/ltests.c b/ltests.c index b666a917c..b78de996a 100644 --- a/ltests.c +++ b/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++; diff --git a/ltm.c b/ltm.c index 756728cfe..29419adf4 100644 --- a/ltm.c +++ b/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; diff --git a/lvm.c b/lvm.c index 3b17a0ada..5df996580 100644 --- a/lvm.c +++ b/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; }