Browse Source

type 'TString' refers directly to the structure inside the union
(union used only for size purposes)

Roberto Ierusalimschy 11 years ago
parent
commit
ca41b43f53
13 changed files with 102 additions and 104 deletions
  1. 3 3
      ldump.c
  2. 5 8
      lgc.c
  3. 6 6
      llex.c
  4. 27 16
      lobject.h
  5. 4 4
      lparser.c
  6. 2 2
      lstate.c
  7. 3 11
      lstate.h
  8. 22 22
      lstring.c
  9. 5 4
      lstring.h
  10. 11 11
      ltable.c
  11. 5 8
      ltests.c
  12. 2 2
      ltm.c
  13. 7 7
      lvm.c

+ 3 - 3
ldump.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldump.c,v 2.31 2014/06/18 13:54:31 roberto Exp roberto $
+** $Id: ldump.c,v 2.32 2014/06/18 18:35:43 roberto Exp roberto $
 ** save precompiled Lua chunks
 ** save precompiled Lua chunks
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -71,7 +71,7 @@ static void DumpString (const TString *s, DumpState *D) {
   if (s == NULL)
   if (s == NULL)
     DumpByte(0, D);
     DumpByte(0, D);
   else {
   else {
-    size_t size = s->tsv.len + 1;  /* include trailing '\0' */
+    size_t size = s->len + 1;  /* include trailing '\0' */
     if (size < 0xFF)
     if (size < 0xFF)
       DumpByte(cast_int(size), D);
       DumpByte(cast_int(size), D);
     else {
     else {
@@ -112,7 +112,7 @@ static void DumpConstants (const Proto *f, DumpState *D) {
       break;
       break;
     case LUA_TSHRSTR:
     case LUA_TSHRSTR:
     case LUA_TLNGSTR:
     case LUA_TLNGSTR:
-      DumpString(rawtsvalue(o), D);
+      DumpString(tsvalue(o), D);
       break;
       break;
     default:
     default:
       lua_assert(0);
       lua_assert(0);

+ 5 - 8
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 2.185 2014/07/17 17:27:49 roberto Exp roberto $
+** $Id: lgc.c,v 2.186 2014/07/18 12:17:54 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -83,9 +83,6 @@
 #define markobject(g,t) \
 #define markobject(g,t) \
   { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
   { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
 
 
-#define markstring(g,t) \
-  { if ((t) && iswhite(ts2gco(t))) reallymarkobject(g, ts2gco(t)); }
-
 static void reallymarkobject (global_State *g, GCObject *o);
 static void reallymarkobject (global_State *g, GCObject *o);
 
 
 
 
@@ -451,15 +448,15 @@ static int traverseproto (global_State *g, Proto *f) {
   int i;
   int i;
   if (f->cache && iswhite(obj2gco(f->cache)))
   if (f->cache && iswhite(obj2gco(f->cache)))
     f->cache = NULL;  /* allow cache to be collected */
     f->cache = NULL;  /* allow cache to be collected */
-  markstring(g, f->source);
+  markobject(g, f->source);
   for (i = 0; i < f->sizek; i++)  /* mark literals */
   for (i = 0; i < f->sizek; i++)  /* mark literals */
     markvalue(g, &f->k[i]);
     markvalue(g, &f->k[i]);
   for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
   for (i = 0; i < f->sizeupvalues; i++)  /* mark upvalue names */
-    markstring(g, f->upvalues[i].name);
+    markobject(g, f->upvalues[i].name);
   for (i = 0; i < f->sizep; i++)  /* mark nested protos */
   for (i = 0; i < f->sizep; i++)  /* mark nested protos */
     markobject(g, f->p[i]);
     markobject(g, f->p[i]);
   for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
   for (i = 0; i < f->sizelocvars; i++)  /* mark local-variable names */
-    markstring(g, f->locvars[i].varname);
+    markobject(g, f->locvars[i].varname);
   return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
   return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
                          sizeof(Proto *) * f->sizep +
                          sizeof(Proto *) * f->sizep +
                          sizeof(TValue) * f->sizek +
                          sizeof(TValue) * f->sizek +
@@ -702,7 +699,7 @@ static void freeobj (lua_State *L, GCObject *o) {
     case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
     case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
     case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
     case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
     case LUA_TSHRSTR:
     case LUA_TSHRSTR:
-      luaS_remove(L, rawgco2ts(o));  /* remove it from hash table */
+      luaS_remove(L, gco2ts(o));  /* remove it from hash table */
       /* go through */
       /* go through */
     case LUA_TLNGSTR: {
     case LUA_TLNGSTR: {
       luaM_freemem(L, o, sizestring(gco2ts(o)));
       luaM_freemem(L, o, sizestring(gco2ts(o)));

+ 6 - 6
llex.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: llex.c,v 2.78 2014/05/21 15:22:02 roberto Exp roberto $
+** $Id: llex.c,v 2.79 2014/07/18 12:17:54 roberto Exp roberto $
 ** Lexical Analyzer
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -67,11 +67,11 @@ static void save (LexState *ls, int c) {
 void luaX_init (lua_State *L) {
 void luaX_init (lua_State *L) {
   int i;
   int i;
   TString *e = luaS_new(L, LUA_ENV);  /* create env name */
   TString *e = luaS_new(L, LUA_ENV);  /* create env name */
-  luaC_fix(L, ts2gco(e));  /* never collect this name */
+  luaC_fix(L, obj2gco(e));  /* never collect this name */
   for (i=0; i<NUM_RESERVED; i++) {
   for (i=0; i<NUM_RESERVED; i++) {
     TString *ts = luaS_new(L, luaX_tokens[i]);
     TString *ts = luaS_new(L, luaX_tokens[i]);
-    luaC_fix(L, ts2gco(ts));  /* reserved words are never collected */
-    ts->tsv.extra = cast_byte(i+1);  /* reserved word */
+    luaC_fix(L, obj2gco(ts));  /* reserved words are never collected */
+    ts->extra = cast_byte(i+1);  /* reserved word */
   }
   }
 }
 }
 
 
@@ -137,7 +137,7 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
     luaC_checkGC(L);
     luaC_checkGC(L);
   }
   }
   else {  /* string already present */
   else {  /* string already present */
-    ts = rawtsvalue(keyfromval(o));  /* re-use value previously stored */
+    ts = tsvalue(keyfromval(o));  /* re-use value previously stored */
   }
   }
   L->top--;  /* remove string from stack */
   L->top--;  /* remove string from stack */
   return ts;
   return ts;
@@ -565,7 +565,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
                                   luaZ_bufflen(ls->buff));
                                   luaZ_bufflen(ls->buff));
           seminfo->ts = ts;
           seminfo->ts = ts;
           if (isreserved(ts))  /* reserved word? */
           if (isreserved(ts))  /* reserved word? */
-            return ts->tsv.extra - 1 + FIRST_RESERVED;
+            return ts->extra - 1 + FIRST_RESERVED;
           else {
           else {
             return TK_NAME;
             return TK_NAME;
           }
           }

+ 27 - 16
lobject.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lobject.h,v 2.96 2014/07/17 17:27:49 roberto Exp roberto $
+** $Id: lobject.h,v 2.97 2014/07/18 12:17:54 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -156,8 +156,7 @@ typedef struct lua_TValue TValue;
 #define fltvalue(o)	check_exp(ttisfloat(o), val_(o).n)
 #define fltvalue(o)	check_exp(ttisfloat(o), val_(o).n)
 #define gcvalue(o)	check_exp(iscollectable(o), val_(o).gc)
 #define gcvalue(o)	check_exp(iscollectable(o), val_(o).gc)
 #define pvalue(o)	check_exp(ttislightuserdata(o), val_(o).p)
 #define pvalue(o)	check_exp(ttislightuserdata(o), val_(o).p)
-#define rawtsvalue(o)	check_exp(ttisstring(o), rawgco2ts(val_(o).gc))
-#define tsvalue(o)	(&rawtsvalue(o)->tsv)
+#define tsvalue(o)	check_exp(ttisstring(o), gco2ts(val_(o).gc))
 #define rawuvalue(o)	check_exp(ttisfulluserdata(o), rawgco2u(val_(o).gc))
 #define rawuvalue(o)	check_exp(ttisfulluserdata(o), rawgco2u(val_(o).gc))
 #define uvalue(o)	(&rawuvalue(o)->uv)
 #define uvalue(o)	(&rawuvalue(o)->uv)
 #define clvalue(o)	check_exp(ttisclosure(o), gco2cl(val_(o).gc))
 #define clvalue(o)	check_exp(ttisclosure(o), gco2cl(val_(o).gc))
@@ -210,7 +209,7 @@ typedef struct lua_TValue TValue;
 
 
 #define setsvalue(L,obj,x) \
 #define setsvalue(L,obj,x) \
   { TValue *io = (obj); TString *x_ = (x); \
   { TValue *io = (obj); TString *x_ = (x); \
-    val_(io).gc = obj2gco(&x_->tsv); settt_(io, ctb(x_->tsv.tt)); \
+    val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
     checkliveness(G(L),io); }
     checkliveness(G(L),io); }
 
 
 #define setuvalue(L,obj,x) \
 #define setuvalue(L,obj,x) \
@@ -299,24 +298,36 @@ typedef TValue *StkId;  /* index to stack elements */
 
 
 /*
 /*
 ** Header for string value; string bytes follow the end of this structure
 ** Header for string value; string bytes follow the end of this structure
+** (aligned according to 'UTString'; see next).
 */
 */
-typedef union TString {
-  L_Umaxalign dummy;  /* ensures maximum alignment for strings */
-  struct {
-    CommonHeader;
-    lu_byte extra;  /* reserved words for short strings; "has hash" for longs */
-    unsigned int hash;
-    size_t len;  /* number of characters in string */
-    union TString *hnext;  /* linked list for hash table */
-  } tsv;
+typedef struct TString {
+  CommonHeader;
+  lu_byte extra;  /* reserved words for short strings; "has hash" for longs */
+  unsigned int hash;
+  size_t len;  /* number of characters in string */
+  struct TString *hnext;  /* linked list for hash table */
 } TString;
 } TString;
 
 
 
 
-/* get the actual string (array of bytes) from a TString */
-#define getstr(ts)	cast(const char *, (ts) + 1)
+/*
+** Ensures that address after this type is always fully aligned.
+*/
+typedef union UTString {
+  L_Umaxalign dummy;  /* ensures maximum alignment for strings */
+  TString tsv;
+} UTString;
+
+
+/*
+** Get the actual string (array of bytes) from a 'TString'.
+** (Access to 'extra' ensures that value is really a 'TString'.)
+*/
+#define getaddrstr(ts)	(cast(char *, (ts)) + sizeof(UTString))
+#define getstr(ts)  \
+	((void)(ts)->extra, cast(const char*, getaddrstr(ts)))
 
 
 /* get the actual string (array of bytes) from a Lua value */
 /* get the actual string (array of bytes) from a Lua value */
-#define svalue(o)       getstr(rawtsvalue(o))
+#define svalue(o)       getstr(tsvalue(o))
 
 
 
 
 /*
 /*

+ 4 - 4
lparser.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lparser.c,v 2.139 2014/06/19 18:27:20 roberto Exp roberto $
+** $Id: lparser.c,v 2.140 2014/07/18 12:17:54 roberto Exp roberto $
 ** Lua Parser
 ** Lua Parser
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -164,7 +164,7 @@ static int registerlocalvar (LexState *ls, TString *varname) {
                   LocVar, SHRT_MAX, "local variables");
                   LocVar, SHRT_MAX, "local variables");
   while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
   while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
   f->locvars[fs->nlocvars].varname = varname;
   f->locvars[fs->nlocvars].varname = varname;
-  luaC_objbarrier(ls->L, f, ts2gco(varname));
+  luaC_objbarrier(ls->L, f, obj2gco(varname));
   return fs->nlocvars++;
   return fs->nlocvars++;
 }
 }
 
 
@@ -232,7 +232,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
   f->upvalues[fs->nups].instack = (v->k == VLOCAL);
   f->upvalues[fs->nups].instack = (v->k == VLOCAL);
   f->upvalues[fs->nups].idx = cast_byte(v->u.info);
   f->upvalues[fs->nups].idx = cast_byte(v->u.info);
   f->upvalues[fs->nups].name = name;
   f->upvalues[fs->nups].name = name;
-  luaC_objbarrier(fs->ls->L, f, ts2gco(name));
+  luaC_objbarrier(fs->ls->L, f, obj2gco(name));
   return fs->nups++;
   return fs->nups++;
 }
 }
 
 
@@ -1630,7 +1630,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
   incr_top(L);
   incr_top(L);
   funcstate.f = cl->p = luaF_newproto(L);
   funcstate.f = cl->p = luaF_newproto(L);
   funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
   funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
-  luaC_objbarrier(L, funcstate.f, ts2gco(funcstate.f->source));
+  luaC_objbarrier(L, funcstate.f, obj2gco(funcstate.f->source));
   lexstate.buff = buff;
   lexstate.buff = buff;
   lexstate.dyd = dyd;
   lexstate.dyd = dyd;
   dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
   dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;

+ 2 - 2
lstate.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.c,v 2.121 2014/02/18 13:46:26 roberto Exp roberto $
+** $Id: lstate.c,v 2.122 2014/07/18 12:17:54 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -206,7 +206,7 @@ static void f_luaopen (lua_State *L, void *ud) {
   luaX_init(L);
   luaX_init(L);
   /* pre-create memory-error message */
   /* pre-create memory-error message */
   g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
   g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
-  luaC_fix(L, ts2gco(g->memerrmsg));  /* it should never be collected */
+  luaC_fix(L, obj2gco(g->memerrmsg));  /* it should never be collected */
   g->gcrunning = 1;  /* allow gc */
   g->gcrunning = 1;  /* allow gc */
   g->version = lua_version(NULL);
   g->version = lua_version(NULL);
   luai_userstateopen(L);
   luai_userstateopen(L);

+ 3 - 11
lstate.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.h,v 2.110 2014/07/17 17:27:49 roberto Exp roberto $
+** $Id: lstate.h,v 2.111 2014/07/18 12:17:54 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -174,7 +174,7 @@ struct lua_State {
 */
 */
 union GCUnion {
 union GCUnion {
   GCObject gc;  /* common header */
   GCObject gc;  /* common header */
-  union TString ts;
+  struct TString ts;
   union Udata u;
   union Udata u;
   union Closure cl;
   union Closure cl;
   struct Table h;
   struct Table h;
@@ -186,9 +186,8 @@ union GCUnion {
 #define cast_u(o)	cast(union GCUnion *, (o))
 #define cast_u(o)	cast(union GCUnion *, (o))
 
 
 /* macros to convert a GCObject into a specific value */
 /* macros to convert a GCObject into a specific value */
-#define rawgco2ts(o)  \
+#define gco2ts(o)  \
 	check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
 	check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
-#define gco2ts(o)	(&rawgco2ts(o)->tsv)
 #define rawgco2u(o)  check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
 #define rawgco2u(o)  check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
 #define gco2u(o)	(&rawgco2u(o)->uv)
 #define gco2u(o)	(&rawgco2u(o)->uv)
 #define gco2lcl(o)  check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
 #define gco2lcl(o)  check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
@@ -204,13 +203,6 @@ union GCUnion {
 #define obj2gco(v) \
 #define obj2gco(v) \
 	check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
 	check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
 
 
-/*
-** macro to convert a TString into a GCObject.
-** (TString is a union, and therefore needs an access slightly different
-** from the other objects.)
-*/
-#define ts2gco(v)	(obj2gco(&(v)->tsv))
-
 
 
 /* actual number of total bytes allocated */
 /* actual number of total bytes allocated */
 #define gettotalbytes(g)	((g)->totalbytes + (g)->GCdebt)
 #define gettotalbytes(g)	((g)->totalbytes + (g)->GCdebt)

+ 22 - 22
lstring.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstring.c,v 2.40 2014/06/18 22:59:29 roberto Exp roberto $
+** $Id: lstring.c,v 2.41 2014/07/18 12:17:54 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -34,10 +34,10 @@
 ** equality for long strings
 ** equality for long strings
 */
 */
 int luaS_eqlngstr (TString *a, TString *b) {
 int luaS_eqlngstr (TString *a, TString *b) {
-  size_t len = a->tsv.len;
-  lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR);
+  size_t len = a->len;
+  lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
   return (a == b) ||  /* same instance or... */
   return (a == b) ||  /* same instance or... */
-    ((len == b->tsv.len) &&  /* equal length and ... */
+    ((len == b->len) &&  /* equal length and ... */
      (memcmp(getstr(a), getstr(b), len) == 0));  /* equal contents */
      (memcmp(getstr(a), getstr(b), len) == 0));  /* equal contents */
 }
 }
 
 
@@ -67,9 +67,9 @@ void luaS_resize (lua_State *L, int newsize) {
     TString *p = tb->hash[i];
     TString *p = tb->hash[i];
     tb->hash[i] = NULL;
     tb->hash[i] = NULL;
     while (p) {  /* for each node in the list */
     while (p) {  /* for each node in the list */
-      TString *hnext = p->tsv.hnext;  /* save next */
-      unsigned int h = lmod(p->tsv.hash, newsize);  /* new position */
-      p->tsv.hnext = tb->hash[h];  /* chain it */
+      TString *hnext = p->hnext;  /* save next */
+      unsigned int h = lmod(p->hash, newsize);  /* new position */
+      p->hnext = tb->hash[h];  /* chain it */
       tb->hash[h] = p;
       tb->hash[h] = p;
       p = hnext;
       p = hnext;
     }
     }
@@ -92,24 +92,24 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
   TString *ts;
   TString *ts;
   GCObject *o;
   GCObject *o;
   size_t totalsize;  /* total size of TString object */
   size_t totalsize;  /* total size of TString object */
-  totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
+  totalsize = sizelstring(l);
   o = luaC_newobj(L, tag, totalsize);
   o = luaC_newobj(L, tag, totalsize);
-  ts = rawgco2ts(o);
-  ts->tsv.len = l;
-  ts->tsv.hash = h;
-  ts->tsv.extra = 0;
-  memcpy(ts+1, str, l*sizeof(char));
-  ((char *)(ts+1))[l] = '\0';  /* ending 0 */
+  ts = gco2ts(o);
+  ts->len = l;
+  ts->hash = h;
+  ts->extra = 0;
+  memcpy(getaddrstr(ts), str, l * sizeof(char));
+  getaddrstr(ts)[l] = '\0';  /* ending 0 */
   return ts;
   return ts;
 }
 }
 
 
 
 
 void luaS_remove (lua_State *L, TString *ts) {
 void luaS_remove (lua_State *L, TString *ts) {
   stringtable *tb = &G(L)->strt;
   stringtable *tb = &G(L)->strt;
-  TString **p = &tb->hash[lmod(ts->tsv.hash, tb->size)];
+  TString **p = &tb->hash[lmod(ts->hash, tb->size)];
   while (*p != ts)  /* find previous element */
   while (*p != ts)  /* find previous element */
-    p = &(*p)->tsv.hnext;
-  *p = (*p)->tsv.hnext;  /* remove element from its list */
+    p = &(*p)->hnext;
+  *p = (*p)->hnext;  /* remove element from its list */
   tb->nuse--;
   tb->nuse--;
 }
 }
 
 
@@ -122,12 +122,12 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
   global_State *g = G(L);
   global_State *g = G(L);
   unsigned int h = luaS_hash(str, l, g->seed);
   unsigned int h = luaS_hash(str, l, g->seed);
   TString **list = &g->strt.hash[lmod(h, g->strt.size)];
   TString **list = &g->strt.hash[lmod(h, g->strt.size)];
-  for (ts = *list; ts != NULL; ts = ts->tsv.hnext) {
-    if (l == ts->tsv.len &&
+  for (ts = *list; ts != NULL; ts = ts->hnext) {
+    if (l == ts->len &&
         (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
         (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
       /* found! */
       /* found! */
-      if (isdead(g, ts2gco(ts)))  /* dead (but not collected yet)? */
-        changewhite(ts2gco(ts));  /* resurrect it */
+      if (isdead(g, obj2gco(ts)))  /* dead (but not collected yet)? */
+        changewhite(obj2gco(ts));  /* resurrect it */
       return ts;
       return ts;
     }
     }
   }
   }
@@ -136,7 +136,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
     list = &g->strt.hash[lmod(h, g->strt.size)];  /* recompute with new size */
     list = &g->strt.hash[lmod(h, g->strt.size)];  /* recompute with new size */
   }
   }
   ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
   ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
-  ts->tsv.hnext = *list;
+  ts->hnext = *list;
   *list = ts;
   *list = ts;
   g->strt.nuse++;
   g->strt.nuse++;
   return ts;
   return ts;

+ 5 - 4
lstring.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstring.h,v 1.53 2014/02/19 13:51:09 roberto Exp roberto $
+** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -12,7 +12,8 @@
 #include "lstate.h"
 #include "lstate.h"
 
 
 
 
-#define sizestring(s)	(sizeof(union TString)+((s)->len+1)*sizeof(char))
+#define sizelstring(l)  (sizeof(union UTString) + ((l) + 1) * sizeof(char))
+#define sizestring(s)	sizelstring((s)->len)
 
 
 #define sizeudata(u)	(sizeof(union Udata)+(u)->len)
 #define sizeudata(u)	(sizeof(union Udata)+(u)->len)
 
 
@@ -23,13 +24,13 @@
 /*
 /*
 ** test whether a string is a reserved word
 ** test whether a string is a reserved word
 */
 */
-#define isreserved(s)	((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0)
+#define isreserved(s)	((s)->tt == LUA_TSHRSTR && (s)->extra > 0)
 
 
 
 
 /*
 /*
 ** equality for short strings, which are always internalized
 ** equality for short strings, which are always internalized
 */
 */
-#define eqshrstr(a,b)	check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b))
+#define eqshrstr(a,b)	check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
 
 
 
 
 LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
 LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);

+ 11 - 11
ltable.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltable.c,v 2.90 2014/06/18 22:59:29 roberto Exp roberto $
+** $Id: ltable.c,v 2.91 2014/06/26 16:17:35 roberto Exp roberto $
 ** Lua tables (hash)
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -52,7 +52,7 @@
 
 
 #define hashpow2(t,n)		(gnode(t, lmod((n), sizenode(t))))
 #define hashpow2(t,n)		(gnode(t, lmod((n), sizenode(t))))
 
 
-#define hashstr(t,str)		hashpow2(t, (str)->tsv.hash)
+#define hashstr(t,str)		hashpow2(t, (str)->hash)
 #define hashboolean(t,p)	hashpow2(t, p)
 #define hashboolean(t,p)	hashpow2(t, p)
 #define hashint(t,i)		hashpow2(t, i)
 #define hashint(t,i)		hashpow2(t, i)
 
 
@@ -116,14 +116,14 @@ static Node *mainposition (const Table *t, const TValue *key) {
     case LUA_TNUMFLT:
     case LUA_TNUMFLT:
       return hashfloat(t, fltvalue(key));
       return hashfloat(t, fltvalue(key));
     case LUA_TSHRSTR:
     case LUA_TSHRSTR:
-      return hashstr(t, rawtsvalue(key));
+      return hashstr(t, tsvalue(key));
     case LUA_TLNGSTR: {
     case LUA_TLNGSTR: {
-      TString *s = rawtsvalue(key);
-      if (s->tsv.extra == 0) {  /* no hash? */
-        s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash);
-        s->tsv.extra = 1;  /* now it has its hash */
+      TString *s = tsvalue(key);
+      if (s->extra == 0) {  /* no hash? */
+        s->hash = luaS_hash(getstr(s), s->len, s->hash);
+        s->extra = 1;  /* now it has its hash */
       }
       }
-      return hashstr(t, rawtsvalue(key));
+      return hashstr(t, tsvalue(key));
     }
     }
     case LUA_TBOOLEAN:
     case LUA_TBOOLEAN:
       return hashboolean(t, bvalue(key));
       return hashboolean(t, bvalue(key));
@@ -501,9 +501,9 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
 */
 */
 const TValue *luaH_getstr (Table *t, TString *key) {
 const TValue *luaH_getstr (Table *t, TString *key) {
   Node *n = hashstr(t, key);
   Node *n = hashstr(t, key);
-  lua_assert(key->tsv.tt == LUA_TSHRSTR);
+  lua_assert(key->tt == LUA_TSHRSTR);
   for (;;) {  /* check whether `key' is somewhere in the chain */
   for (;;) {  /* check whether `key' is somewhere in the chain */
-    if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))
+    if (ttisshrstring(gkey(n)) && eqshrstr(tsvalue(gkey(n)), key))
       return gval(n);  /* that's it */
       return gval(n);  /* that's it */
     else {
     else {
       int nx = gnext(n);
       int nx = gnext(n);
@@ -520,7 +520,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
 */
 */
 const TValue *luaH_get (Table *t, const TValue *key) {
 const TValue *luaH_get (Table *t, const TValue *key) {
   switch (ttype(key)) {
   switch (ttype(key)) {
-    case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
+    case LUA_TSHRSTR: return luaH_getstr(t, tsvalue(key));
     case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
     case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
     case LUA_TNIL: return luaO_nilobject;
     case LUA_TNIL: return luaO_nilobject;
     case LUA_TNUMFLT: {
     case LUA_TNUMFLT: {

+ 5 - 8
ltests.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltests.c,v 2.177 2014/07/17 17:27:49 roberto Exp roberto $
+** $Id: ltests.c,v 2.178 2014/07/18 12:17:54 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -210,9 +210,6 @@ static int testobjref (global_State *g, GCObject *f, GCObject *t) {
 #define checkobjref(g,f,t)  \
 #define checkobjref(g,f,t)  \
 	{ if (t) lua_longassert(testobjref(g,f,obj2gco(t))); }
 	{ if (t) lua_longassert(testobjref(g,f,obj2gco(t))); }
 
 
-#define checkstrref(g,f,t)  \
-	{ if (t) lua_longassert(testobjref(g,f,ts2gco(t))); }
-
 
 
 static void checkvalref (global_State *g, GCObject *f, const TValue *t) {
 static void checkvalref (global_State *g, GCObject *f, const TValue *t) {
   lua_assert(!iscollectable(t) ||
   lua_assert(!iscollectable(t) ||
@@ -245,17 +242,17 @@ static void checkproto (global_State *g, Proto *f) {
   int i;
   int i;
   GCObject *fgc = obj2gco(f);
   GCObject *fgc = obj2gco(f);
   checkobjref(g, fgc, f->cache);
   checkobjref(g, fgc, f->cache);
-  checkstrref(g, fgc, f->source);
+  checkobjref(g, fgc, f->source);
   for (i=0; i<f->sizek; i++) {
   for (i=0; i<f->sizek; i++) {
     if (ttisstring(f->k + i))
     if (ttisstring(f->k + i))
       checkobjref(g, fgc, tsvalue(f->k + i));
       checkobjref(g, fgc, tsvalue(f->k + i));
   }
   }
   for (i=0; i<f->sizeupvalues; i++)
   for (i=0; i<f->sizeupvalues; i++)
-    checkstrref(g, fgc, f->upvalues[i].name);
+    checkobjref(g, fgc, f->upvalues[i].name);
   for (i=0; i<f->sizep; i++)
   for (i=0; i<f->sizep; i++)
     checkobjref(g, fgc, f->p[i]);
     checkobjref(g, fgc, f->p[i]);
   for (i=0; i<f->sizelocvars; i++)
   for (i=0; i<f->sizelocvars; i++)
-    checkstrref(g, fgc, f->locvars[i].varname);
+    checkobjref(g, fgc, f->locvars[i].varname);
 }
 }
 
 
 
 
@@ -701,7 +698,7 @@ static int string_query (lua_State *L) {
   else if (s < tb->size) {
   else if (s < tb->size) {
     TString *ts;
     TString *ts;
     int n = 0;
     int n = 0;
-    for (ts = tb->hash[s]; ts != NULL; ts = ts->tsv.hnext) {
+    for (ts = tb->hash[s]; ts != NULL; ts = ts->hnext) {
       setsvalue2s(L, L->top, ts);
       setsvalue2s(L, L->top, ts);
       api_incr_top(L);
       api_incr_top(L);
       n++;
       n++;

+ 2 - 2
ltm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltm.c,v 2.27 2014/06/10 18:53:18 roberto Exp roberto $
+** $Id: ltm.c,v 2.28 2014/07/18 12:17:54 roberto Exp roberto $
 ** Tag methods
 ** Tag methods
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -45,7 +45,7 @@ void luaT_init (lua_State *L) {
   int i;
   int i;
   for (i=0; i<TM_N; i++) {
   for (i=0; i<TM_N; i++) {
     G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
     G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
-    luaC_fix(L, ts2gco(G(L)->tmname[i]));  /* never collect these names */
+    luaC_fix(L, obj2gco(G(L)->tmname[i]));  /* never collect these names */
   }
   }
 }
 }
 
 

+ 7 - 7
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 2.217 2014/06/30 19:48:08 roberto Exp roberto $
+** $Id: lvm.c,v 2.218 2014/07/17 12:30:53 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -262,9 +262,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
 */
 */
 static int l_strcmp (const TString *ls, const TString *rs) {
 static int l_strcmp (const TString *ls, const TString *rs) {
   const char *l = getstr(ls);
   const char *l = getstr(ls);
-  size_t ll = ls->tsv.len;
+  size_t ll = ls->len;
   const char *r = getstr(rs);
   const char *r = getstr(rs);
-  size_t lr = rs->tsv.len;
+  size_t lr = rs->len;
   for (;;) {  /* for each segment */
   for (;;) {  /* for each segment */
     int temp = strcoll(l, r);
     int temp = strcoll(l, r);
     if (temp != 0)  /* not equal? */
     if (temp != 0)  /* not equal? */
@@ -294,7 +294,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
   else if (tofloat(l, &nl) && tofloat(r, &nr))  /* both are numbers? */
   else if (tofloat(l, &nl) && tofloat(r, &nr))  /* both are numbers? */
     return luai_numlt(nl, nr);
     return luai_numlt(nl, nr);
   else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
   else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
-    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
+    return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
   else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0)  /* no metamethod? */
   else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0)  /* no metamethod? */
     luaG_ordererror(L, l, r);  /* error */
     luaG_ordererror(L, l, r);  /* error */
   return res;
   return res;
@@ -312,7 +312,7 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
   else if (tofloat(l, &nl) && tofloat(r, &nr))  /* both are numbers? */
   else if (tofloat(l, &nl) && tofloat(r, &nr))  /* both are numbers? */
     return luai_numle(nl, nr);
     return luai_numle(nl, nr);
   else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
   else if (ttisstring(l) && ttisstring(r))  /* both are strings? */
-    return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
+    return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
   else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0)  /* first try `le' */
   else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0)  /* first try `le' */
     return res;
     return res;
   else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0)  /* else try `lt' */
   else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0)  /* else try `lt' */
@@ -345,8 +345,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
     case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
     case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
     case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
     case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
     case LUA_TLCF: return fvalue(t1) == fvalue(t2);
     case LUA_TLCF: return fvalue(t1) == fvalue(t2);
-    case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
-    case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
+    case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2));
+    case LUA_TLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2));
     case LUA_TUSERDATA: {
     case LUA_TUSERDATA: {
       if (uvalue(t1) == uvalue(t2)) return 1;
       if (uvalue(t1) == uvalue(t2)) return 1;
       else if (L == NULL) return 0;
       else if (L == NULL) return 0;