2
0
Эх сурвалжийг харах

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

Roberto Ierusalimschy 11 жил өмнө
parent
commit
ca41b43f53
13 өөрчлөгдсөн 102 нэмэгдсэн , 104 устгасан
  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;