summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-07-18 10:36:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-07-18 10:36:14 -0300
commitca41b43f53562e64abe433d6346d174c92548603 (patch)
tree03f7a99f76359fc1e0bbc45fc13e579ff2aafabb
parent3511e186cde4b78f268d17199d0f46fb3eaa9638 (diff)
downloadlua-ca41b43f53562e64abe433d6346d174c92548603.tar.gz
lua-ca41b43f53562e64abe433d6346d174c92548603.tar.bz2
lua-ca41b43f53562e64abe433d6346d174c92548603.zip
type 'TString' refers directly to the structure inside the union
(union used only for size purposes)
-rw-r--r--ldump.c6
-rw-r--r--lgc.c13
-rw-r--r--llex.c12
-rw-r--r--lobject.h43
-rw-r--r--lparser.c8
-rw-r--r--lstate.c4
-rw-r--r--lstate.h14
-rw-r--r--lstring.c44
-rw-r--r--lstring.h9
-rw-r--r--ltable.c22
-rw-r--r--ltests.c13
-rw-r--r--ltm.c4
-rw-r--r--lvm.c14
13 files changed, 102 insertions, 104 deletions
diff --git a/ldump.c b/ldump.c
index 4155d314..a8c66183 100644
--- a/ldump.c
+++ b/ldump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldump.c,v 2.31 2014/06/18 13:54:31 roberto Exp roberto $ 2** $Id: ldump.c,v 2.32 2014/06/18 18:35:43 roberto Exp roberto $
3** save precompiled Lua chunks 3** save precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -71,7 +71,7 @@ static void DumpString (const TString *s, DumpState *D) {
71 if (s == NULL) 71 if (s == NULL)
72 DumpByte(0, D); 72 DumpByte(0, D);
73 else { 73 else {
74 size_t size = s->tsv.len + 1; /* include trailing '\0' */ 74 size_t size = s->len + 1; /* include trailing '\0' */
75 if (size < 0xFF) 75 if (size < 0xFF)
76 DumpByte(cast_int(size), D); 76 DumpByte(cast_int(size), D);
77 else { 77 else {
@@ -112,7 +112,7 @@ static void DumpConstants (const Proto *f, DumpState *D) {
112 break; 112 break;
113 case LUA_TSHRSTR: 113 case LUA_TSHRSTR:
114 case LUA_TLNGSTR: 114 case LUA_TLNGSTR:
115 DumpString(rawtsvalue(o), D); 115 DumpString(tsvalue(o), D);
116 break; 116 break;
117 default: 117 default:
118 lua_assert(0); 118 lua_assert(0);
diff --git a/lgc.c b/lgc.c
index ac1c6a46..87d6ca6c 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.185 2014/07/17 17:27:49 roberto Exp roberto $ 2** $Id: lgc.c,v 2.186 2014/07/18 12:17:54 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -83,9 +83,6 @@
83#define markobject(g,t) \ 83#define markobject(g,t) \
84 { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); } 84 { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
85 85
86#define markstring(g,t) \
87 { if ((t) && iswhite(ts2gco(t))) reallymarkobject(g, ts2gco(t)); }
88
89static void reallymarkobject (global_State *g, GCObject *o); 86static void reallymarkobject (global_State *g, GCObject *o);
90 87
91 88
@@ -451,15 +448,15 @@ static int traverseproto (global_State *g, Proto *f) {
451 int i; 448 int i;
452 if (f->cache && iswhite(obj2gco(f->cache))) 449 if (f->cache && iswhite(obj2gco(f->cache)))
453 f->cache = NULL; /* allow cache to be collected */ 450 f->cache = NULL; /* allow cache to be collected */
454 markstring(g, f->source); 451 markobject(g, f->source);
455 for (i = 0; i < f->sizek; i++) /* mark literals */ 452 for (i = 0; i < f->sizek; i++) /* mark literals */
456 markvalue(g, &f->k[i]); 453 markvalue(g, &f->k[i]);
457 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ 454 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
458 markstring(g, f->upvalues[i].name); 455 markobject(g, f->upvalues[i].name);
459 for (i = 0; i < f->sizep; i++) /* mark nested protos */ 456 for (i = 0; i < f->sizep; i++) /* mark nested protos */
460 markobject(g, f->p[i]); 457 markobject(g, f->p[i]);
461 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ 458 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
462 markstring(g, f->locvars[i].varname); 459 markobject(g, f->locvars[i].varname);
463 return sizeof(Proto) + sizeof(Instruction) * f->sizecode + 460 return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
464 sizeof(Proto *) * f->sizep + 461 sizeof(Proto *) * f->sizep +
465 sizeof(TValue) * f->sizek + 462 sizeof(TValue) * f->sizek +
@@ -702,7 +699,7 @@ static void freeobj (lua_State *L, GCObject *o) {
702 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; 699 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
703 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; 700 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
704 case LUA_TSHRSTR: 701 case LUA_TSHRSTR:
705 luaS_remove(L, rawgco2ts(o)); /* remove it from hash table */ 702 luaS_remove(L, gco2ts(o)); /* remove it from hash table */
706 /* go through */ 703 /* go through */
707 case LUA_TLNGSTR: { 704 case LUA_TLNGSTR: {
708 luaM_freemem(L, o, sizestring(gco2ts(o))); 705 luaM_freemem(L, o, sizestring(gco2ts(o)));
diff --git a/llex.c b/llex.c
index 6b5dd7d5..4f8756a6 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 2.78 2014/05/21 15:22:02 roberto Exp roberto $ 2** $Id: llex.c,v 2.79 2014/07/18 12:17:54 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -67,11 +67,11 @@ static void save (LexState *ls, int c) {
67void luaX_init (lua_State *L) { 67void luaX_init (lua_State *L) {
68 int i; 68 int i;
69 TString *e = luaS_new(L, LUA_ENV); /* create env name */ 69 TString *e = luaS_new(L, LUA_ENV); /* create env name */
70 luaC_fix(L, ts2gco(e)); /* never collect this name */ 70 luaC_fix(L, obj2gco(e)); /* never collect this name */
71 for (i=0; i<NUM_RESERVED; i++) { 71 for (i=0; i<NUM_RESERVED; i++) {
72 TString *ts = luaS_new(L, luaX_tokens[i]); 72 TString *ts = luaS_new(L, luaX_tokens[i]);
73 luaC_fix(L, ts2gco(ts)); /* reserved words are never collected */ 73 luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */
74 ts->tsv.extra = cast_byte(i+1); /* reserved word */ 74 ts->extra = cast_byte(i+1); /* reserved word */
75 } 75 }
76} 76}
77 77
@@ -137,7 +137,7 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
137 luaC_checkGC(L); 137 luaC_checkGC(L);
138 } 138 }
139 else { /* string already present */ 139 else { /* string already present */
140 ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */ 140 ts = tsvalue(keyfromval(o)); /* re-use value previously stored */
141 } 141 }
142 L->top--; /* remove string from stack */ 142 L->top--; /* remove string from stack */
143 return ts; 143 return ts;
@@ -565,7 +565,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
565 luaZ_bufflen(ls->buff)); 565 luaZ_bufflen(ls->buff));
566 seminfo->ts = ts; 566 seminfo->ts = ts;
567 if (isreserved(ts)) /* reserved word? */ 567 if (isreserved(ts)) /* reserved word? */
568 return ts->tsv.extra - 1 + FIRST_RESERVED; 568 return ts->extra - 1 + FIRST_RESERVED;
569 else { 569 else {
570 return TK_NAME; 570 return TK_NAME;
571 } 571 }
diff --git a/lobject.h b/lobject.h
index e49f8dcc..3bf7045a 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.96 2014/07/17 17:27:49 roberto Exp roberto $ 2** $Id: lobject.h,v 2.97 2014/07/18 12:17:54 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -156,8 +156,7 @@ typedef struct lua_TValue TValue;
156#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) 156#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
157#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) 157#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
158#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) 158#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
159#define rawtsvalue(o) check_exp(ttisstring(o), rawgco2ts(val_(o).gc)) 159#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
160#define tsvalue(o) (&rawtsvalue(o)->tsv)
161#define rawuvalue(o) check_exp(ttisfulluserdata(o), rawgco2u(val_(o).gc)) 160#define rawuvalue(o) check_exp(ttisfulluserdata(o), rawgco2u(val_(o).gc))
162#define uvalue(o) (&rawuvalue(o)->uv) 161#define uvalue(o) (&rawuvalue(o)->uv)
163#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) 162#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
@@ -210,7 +209,7 @@ typedef struct lua_TValue TValue;
210 209
211#define setsvalue(L,obj,x) \ 210#define setsvalue(L,obj,x) \
212 { TValue *io = (obj); TString *x_ = (x); \ 211 { TValue *io = (obj); TString *x_ = (x); \
213 val_(io).gc = obj2gco(&x_->tsv); settt_(io, ctb(x_->tsv.tt)); \ 212 val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
214 checkliveness(G(L),io); } 213 checkliveness(G(L),io); }
215 214
216#define setuvalue(L,obj,x) \ 215#define setuvalue(L,obj,x) \
@@ -299,24 +298,36 @@ typedef TValue *StkId; /* index to stack elements */
299 298
300/* 299/*
301** Header for string value; string bytes follow the end of this structure 300** Header for string value; string bytes follow the end of this structure
301** (aligned according to 'UTString'; see next).
302*/ 302*/
303typedef union TString { 303typedef struct TString {
304 L_Umaxalign dummy; /* ensures maximum alignment for strings */ 304 CommonHeader;
305 struct { 305 lu_byte extra; /* reserved words for short strings; "has hash" for longs */
306 CommonHeader; 306 unsigned int hash;
307 lu_byte extra; /* reserved words for short strings; "has hash" for longs */ 307 size_t len; /* number of characters in string */
308 unsigned int hash; 308 struct TString *hnext; /* linked list for hash table */
309 size_t len; /* number of characters in string */
310 union TString *hnext; /* linked list for hash table */
311 } tsv;
312} TString; 309} TString;
313 310
314 311
315/* get the actual string (array of bytes) from a TString */ 312/*
316#define getstr(ts) cast(const char *, (ts) + 1) 313** Ensures that address after this type is always fully aligned.
314*/
315typedef union UTString {
316 L_Umaxalign dummy; /* ensures maximum alignment for strings */
317 TString tsv;
318} UTString;
319
320
321/*
322** Get the actual string (array of bytes) from a 'TString'.
323** (Access to 'extra' ensures that value is really a 'TString'.)
324*/
325#define getaddrstr(ts) (cast(char *, (ts)) + sizeof(UTString))
326#define getstr(ts) \
327 ((void)(ts)->extra, cast(const char*, getaddrstr(ts)))
317 328
318/* get the actual string (array of bytes) from a Lua value */ 329/* get the actual string (array of bytes) from a Lua value */
319#define svalue(o) getstr(rawtsvalue(o)) 330#define svalue(o) getstr(tsvalue(o))
320 331
321 332
322/* 333/*
diff --git a/lparser.c b/lparser.c
index 5fec4583..d1e5db4d 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.139 2014/06/19 18:27:20 roberto Exp roberto $ 2** $Id: lparser.c,v 2.140 2014/07/18 12:17:54 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -164,7 +164,7 @@ static int registerlocalvar (LexState *ls, TString *varname) {
164 LocVar, SHRT_MAX, "local variables"); 164 LocVar, SHRT_MAX, "local variables");
165 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; 165 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
166 f->locvars[fs->nlocvars].varname = varname; 166 f->locvars[fs->nlocvars].varname = varname;
167 luaC_objbarrier(ls->L, f, ts2gco(varname)); 167 luaC_objbarrier(ls->L, f, obj2gco(varname));
168 return fs->nlocvars++; 168 return fs->nlocvars++;
169} 169}
170 170
@@ -232,7 +232,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
232 f->upvalues[fs->nups].instack = (v->k == VLOCAL); 232 f->upvalues[fs->nups].instack = (v->k == VLOCAL);
233 f->upvalues[fs->nups].idx = cast_byte(v->u.info); 233 f->upvalues[fs->nups].idx = cast_byte(v->u.info);
234 f->upvalues[fs->nups].name = name; 234 f->upvalues[fs->nups].name = name;
235 luaC_objbarrier(fs->ls->L, f, ts2gco(name)); 235 luaC_objbarrier(fs->ls->L, f, obj2gco(name));
236 return fs->nups++; 236 return fs->nups++;
237} 237}
238 238
@@ -1630,7 +1630,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
1630 incr_top(L); 1630 incr_top(L);
1631 funcstate.f = cl->p = luaF_newproto(L); 1631 funcstate.f = cl->p = luaF_newproto(L);
1632 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ 1632 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
1633 luaC_objbarrier(L, funcstate.f, ts2gco(funcstate.f->source)); 1633 luaC_objbarrier(L, funcstate.f, obj2gco(funcstate.f->source));
1634 lexstate.buff = buff; 1634 lexstate.buff = buff;
1635 lexstate.dyd = dyd; 1635 lexstate.dyd = dyd;
1636 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; 1636 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
diff --git a/lstate.c b/lstate.c
index bab3abaf..607af60a 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.121 2014/02/18 13:46:26 roberto Exp roberto $ 2** $Id: lstate.c,v 2.122 2014/07/18 12:17:54 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -206,7 +206,7 @@ static void f_luaopen (lua_State *L, void *ud) {
206 luaX_init(L); 206 luaX_init(L);
207 /* pre-create memory-error message */ 207 /* pre-create memory-error message */
208 g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 208 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
209 luaC_fix(L, ts2gco(g->memerrmsg)); /* it should never be collected */ 209 luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
210 g->gcrunning = 1; /* allow gc */ 210 g->gcrunning = 1; /* allow gc */
211 g->version = lua_version(NULL); 211 g->version = lua_version(NULL);
212 luai_userstateopen(L); 212 luai_userstateopen(L);
diff --git a/lstate.h b/lstate.h
index 69c91b63..662e925a 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.110 2014/07/17 17:27:49 roberto Exp roberto $ 2** $Id: lstate.h,v 2.111 2014/07/18 12:17:54 roberto Exp roberto $
3** Global State 3** Global State
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -174,7 +174,7 @@ struct lua_State {
174*/ 174*/
175union GCUnion { 175union GCUnion {
176 GCObject gc; /* common header */ 176 GCObject gc; /* common header */
177 union TString ts; 177 struct TString ts;
178 union Udata u; 178 union Udata u;
179 union Closure cl; 179 union Closure cl;
180 struct Table h; 180 struct Table h;
@@ -186,9 +186,8 @@ union GCUnion {
186#define cast_u(o) cast(union GCUnion *, (o)) 186#define cast_u(o) cast(union GCUnion *, (o))
187 187
188/* macros to convert a GCObject into a specific value */ 188/* macros to convert a GCObject into a specific value */
189#define rawgco2ts(o) \ 189#define gco2ts(o) \
190 check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) 190 check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
191#define gco2ts(o) (&rawgco2ts(o)->tsv)
192#define rawgco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u)) 191#define rawgco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
193#define gco2u(o) (&rawgco2u(o)->uv) 192#define gco2u(o) (&rawgco2u(o)->uv)
194#define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l)) 193#define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
@@ -204,13 +203,6 @@ union GCUnion {
204#define obj2gco(v) \ 203#define obj2gco(v) \
205 check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc))) 204 check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
206 205
207/*
208** macro to convert a TString into a GCObject.
209** (TString is a union, and therefore needs an access slightly different
210** from the other objects.)
211*/
212#define ts2gco(v) (obj2gco(&(v)->tsv))
213
214 206
215/* actual number of total bytes allocated */ 207/* actual number of total bytes allocated */
216#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) 208#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt)
diff --git a/lstring.c b/lstring.c
index fd4351ab..fdd76300 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.40 2014/06/18 22:59:29 roberto Exp roberto $ 2** $Id: lstring.c,v 2.41 2014/07/18 12:17:54 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -34,10 +34,10 @@
34** equality for long strings 34** equality for long strings
35*/ 35*/
36int luaS_eqlngstr (TString *a, TString *b) { 36int luaS_eqlngstr (TString *a, TString *b) {
37 size_t len = a->tsv.len; 37 size_t len = a->len;
38 lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); 38 lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
39 return (a == b) || /* same instance or... */ 39 return (a == b) || /* same instance or... */
40 ((len == b->tsv.len) && /* equal length and ... */ 40 ((len == b->len) && /* equal length and ... */
41 (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 41 (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
42} 42}
43 43
@@ -67,9 +67,9 @@ void luaS_resize (lua_State *L, int newsize) {
67 TString *p = tb->hash[i]; 67 TString *p = tb->hash[i];
68 tb->hash[i] = NULL; 68 tb->hash[i] = NULL;
69 while (p) { /* for each node in the list */ 69 while (p) { /* for each node in the list */
70 TString *hnext = p->tsv.hnext; /* save next */ 70 TString *hnext = p->hnext; /* save next */
71 unsigned int h = lmod(p->tsv.hash, newsize); /* new position */ 71 unsigned int h = lmod(p->hash, newsize); /* new position */
72 p->tsv.hnext = tb->hash[h]; /* chain it */ 72 p->hnext = tb->hash[h]; /* chain it */
73 tb->hash[h] = p; 73 tb->hash[h] = p;
74 p = hnext; 74 p = hnext;
75 } 75 }
@@ -92,24 +92,24 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
92 TString *ts; 92 TString *ts;
93 GCObject *o; 93 GCObject *o;
94 size_t totalsize; /* total size of TString object */ 94 size_t totalsize; /* total size of TString object */
95 totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); 95 totalsize = sizelstring(l);
96 o = luaC_newobj(L, tag, totalsize); 96 o = luaC_newobj(L, tag, totalsize);
97 ts = rawgco2ts(o); 97 ts = gco2ts(o);
98 ts->tsv.len = l; 98 ts->len = l;
99 ts->tsv.hash = h; 99 ts->hash = h;
100 ts->tsv.extra = 0; 100 ts->extra = 0;
101 memcpy(ts+1, str, l*sizeof(char)); 101 memcpy(getaddrstr(ts), str, l * sizeof(char));
102 ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 102 getaddrstr(ts)[l] = '\0'; /* ending 0 */
103 return ts; 103 return ts;
104} 104}
105 105
106 106
107void luaS_remove (lua_State *L, TString *ts) { 107void luaS_remove (lua_State *L, TString *ts) {
108 stringtable *tb = &G(L)->strt; 108 stringtable *tb = &G(L)->strt;
109 TString **p = &tb->hash[lmod(ts->tsv.hash, tb->size)]; 109 TString **p = &tb->hash[lmod(ts->hash, tb->size)];
110 while (*p != ts) /* find previous element */ 110 while (*p != ts) /* find previous element */
111 p = &(*p)->tsv.hnext; 111 p = &(*p)->hnext;
112 *p = (*p)->tsv.hnext; /* remove element from its list */ 112 *p = (*p)->hnext; /* remove element from its list */
113 tb->nuse--; 113 tb->nuse--;
114} 114}
115 115
@@ -122,12 +122,12 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
122 global_State *g = G(L); 122 global_State *g = G(L);
123 unsigned int h = luaS_hash(str, l, g->seed); 123 unsigned int h = luaS_hash(str, l, g->seed);
124 TString **list = &g->strt.hash[lmod(h, g->strt.size)]; 124 TString **list = &g->strt.hash[lmod(h, g->strt.size)];
125 for (ts = *list; ts != NULL; ts = ts->tsv.hnext) { 125 for (ts = *list; ts != NULL; ts = ts->hnext) {
126 if (l == ts->tsv.len && 126 if (l == ts->len &&
127 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 127 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
128 /* found! */ 128 /* found! */
129 if (isdead(g, ts2gco(ts))) /* dead (but not collected yet)? */ 129 if (isdead(g, obj2gco(ts))) /* dead (but not collected yet)? */
130 changewhite(ts2gco(ts)); /* resurrect it */ 130 changewhite(obj2gco(ts)); /* resurrect it */
131 return ts; 131 return ts;
132 } 132 }
133 } 133 }
@@ -136,7 +136,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
136 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ 136 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
137 } 137 }
138 ts = createstrobj(L, str, l, LUA_TSHRSTR, h); 138 ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
139 ts->tsv.hnext = *list; 139 ts->hnext = *list;
140 *list = ts; 140 *list = ts;
141 g->strt.nuse++; 141 g->strt.nuse++;
142 return ts; 142 return ts;
diff --git a/lstring.h b/lstring.h
index ecbe1cfb..f4f60a20 100644
--- a/lstring.h
+++ b/lstring.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.h,v 1.53 2014/02/19 13:51:09 roberto Exp roberto $ 2** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp roberto $
3** String table (keep all strings handled by Lua) 3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -12,7 +12,8 @@
12#include "lstate.h" 12#include "lstate.h"
13 13
14 14
15#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) 15#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
16#define sizestring(s) sizelstring((s)->len)
16 17
17#define sizeudata(u) (sizeof(union Udata)+(u)->len) 18#define sizeudata(u) (sizeof(union Udata)+(u)->len)
18 19
@@ -23,13 +24,13 @@
23/* 24/*
24** test whether a string is a reserved word 25** test whether a string is a reserved word
25*/ 26*/
26#define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) 27#define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0)
27 28
28 29
29/* 30/*
30** equality for short strings, which are always internalized 31** equality for short strings, which are always internalized
31*/ 32*/
32#define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) 33#define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
33 34
34 35
35LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 36LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
diff --git a/ltable.c b/ltable.c
index 712b9814..a234bebb 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.90 2014/06/18 22:59:29 roberto Exp roberto $ 2** $Id: ltable.c,v 2.91 2014/06/26 16:17:35 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -52,7 +52,7 @@
52 52
53#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) 53#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
54 54
55#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) 55#define hashstr(t,str) hashpow2(t, (str)->hash)
56#define hashboolean(t,p) hashpow2(t, p) 56#define hashboolean(t,p) hashpow2(t, p)
57#define hashint(t,i) hashpow2(t, i) 57#define hashint(t,i) hashpow2(t, i)
58 58
@@ -116,14 +116,14 @@ static Node *mainposition (const Table *t, const TValue *key) {
116 case LUA_TNUMFLT: 116 case LUA_TNUMFLT:
117 return hashfloat(t, fltvalue(key)); 117 return hashfloat(t, fltvalue(key));
118 case LUA_TSHRSTR: 118 case LUA_TSHRSTR:
119 return hashstr(t, rawtsvalue(key)); 119 return hashstr(t, tsvalue(key));
120 case LUA_TLNGSTR: { 120 case LUA_TLNGSTR: {
121 TString *s = rawtsvalue(key); 121 TString *s = tsvalue(key);
122 if (s->tsv.extra == 0) { /* no hash? */ 122 if (s->extra == 0) { /* no hash? */
123 s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); 123 s->hash = luaS_hash(getstr(s), s->len, s->hash);
124 s->tsv.extra = 1; /* now it has its hash */ 124 s->extra = 1; /* now it has its hash */
125 } 125 }
126 return hashstr(t, rawtsvalue(key)); 126 return hashstr(t, tsvalue(key));
127 } 127 }
128 case LUA_TBOOLEAN: 128 case LUA_TBOOLEAN:
129 return hashboolean(t, bvalue(key)); 129 return hashboolean(t, bvalue(key));
@@ -501,9 +501,9 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
501*/ 501*/
502const TValue *luaH_getstr (Table *t, TString *key) { 502const TValue *luaH_getstr (Table *t, TString *key) {
503 Node *n = hashstr(t, key); 503 Node *n = hashstr(t, key);
504 lua_assert(key->tsv.tt == LUA_TSHRSTR); 504 lua_assert(key->tt == LUA_TSHRSTR);
505 for (;;) { /* check whether `key' is somewhere in the chain */ 505 for (;;) { /* check whether `key' is somewhere in the chain */
506 if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) 506 if (ttisshrstring(gkey(n)) && eqshrstr(tsvalue(gkey(n)), key))
507 return gval(n); /* that's it */ 507 return gval(n); /* that's it */
508 else { 508 else {
509 int nx = gnext(n); 509 int nx = gnext(n);
@@ -520,7 +520,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
520*/ 520*/
521const TValue *luaH_get (Table *t, const TValue *key) { 521const TValue *luaH_get (Table *t, const TValue *key) {
522 switch (ttype(key)) { 522 switch (ttype(key)) {
523 case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); 523 case LUA_TSHRSTR: return luaH_getstr(t, tsvalue(key));
524 case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); 524 case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
525 case LUA_TNIL: return luaO_nilobject; 525 case LUA_TNIL: return luaO_nilobject;
526 case LUA_TNUMFLT: { 526 case LUA_TNUMFLT: {
diff --git a/ltests.c b/ltests.c
index 13cfa043..fde7fdcd 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.177 2014/07/17 17:27:49 roberto Exp roberto $ 2** $Id: ltests.c,v 2.178 2014/07/18 12:17:54 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -210,9 +210,6 @@ static int testobjref (global_State *g, GCObject *f, GCObject *t) {
210#define checkobjref(g,f,t) \ 210#define checkobjref(g,f,t) \
211 { if (t) lua_longassert(testobjref(g,f,obj2gco(t))); } 211 { if (t) lua_longassert(testobjref(g,f,obj2gco(t))); }
212 212
213#define checkstrref(g,f,t) \
214 { if (t) lua_longassert(testobjref(g,f,ts2gco(t))); }
215
216 213
217static void checkvalref (global_State *g, GCObject *f, const TValue *t) { 214static void checkvalref (global_State *g, GCObject *f, const TValue *t) {
218 lua_assert(!iscollectable(t) || 215 lua_assert(!iscollectable(t) ||
@@ -245,17 +242,17 @@ static void checkproto (global_State *g, Proto *f) {
245 int i; 242 int i;
246 GCObject *fgc = obj2gco(f); 243 GCObject *fgc = obj2gco(f);
247 checkobjref(g, fgc, f->cache); 244 checkobjref(g, fgc, f->cache);
248 checkstrref(g, fgc, f->source); 245 checkobjref(g, fgc, f->source);
249 for (i=0; i<f->sizek; i++) { 246 for (i=0; i<f->sizek; i++) {
250 if (ttisstring(f->k + i)) 247 if (ttisstring(f->k + i))
251 checkobjref(g, fgc, tsvalue(f->k + i)); 248 checkobjref(g, fgc, tsvalue(f->k + i));
252 } 249 }
253 for (i=0; i<f->sizeupvalues; i++) 250 for (i=0; i<f->sizeupvalues; i++)
254 checkstrref(g, fgc, f->upvalues[i].name); 251 checkobjref(g, fgc, f->upvalues[i].name);
255 for (i=0; i<f->sizep; i++) 252 for (i=0; i<f->sizep; i++)
256 checkobjref(g, fgc, f->p[i]); 253 checkobjref(g, fgc, f->p[i]);
257 for (i=0; i<f->sizelocvars; i++) 254 for (i=0; i<f->sizelocvars; i++)
258 checkstrref(g, fgc, f->locvars[i].varname); 255 checkobjref(g, fgc, f->locvars[i].varname);
259} 256}
260 257
261 258
@@ -701,7 +698,7 @@ static int string_query (lua_State *L) {
701 else if (s < tb->size) { 698 else if (s < tb->size) {
702 TString *ts; 699 TString *ts;
703 int n = 0; 700 int n = 0;
704 for (ts = tb->hash[s]; ts != NULL; ts = ts->tsv.hnext) { 701 for (ts = tb->hash[s]; ts != NULL; ts = ts->hnext) {
705 setsvalue2s(L, L->top, ts); 702 setsvalue2s(L, L->top, ts);
706 api_incr_top(L); 703 api_incr_top(L);
707 n++; 704 n++;
diff --git a/ltm.c b/ltm.c
index dfe0cc4b..396b28ea 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.27 2014/06/10 18:53:18 roberto Exp roberto $ 2** $Id: ltm.c,v 2.28 2014/07/18 12:17:54 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -45,7 +45,7 @@ void luaT_init (lua_State *L) {
45 int i; 45 int i;
46 for (i=0; i<TM_N; i++) { 46 for (i=0; i<TM_N; i++) {
47 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); 47 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
48 luaC_fix(L, ts2gco(G(L)->tmname[i])); /* never collect these names */ 48 luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */
49 } 49 }
50} 50}
51 51
diff --git a/lvm.c b/lvm.c
index 694d5546..49115c4b 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.217 2014/06/30 19:48:08 roberto Exp roberto $ 2** $Id: lvm.c,v 2.218 2014/07/17 12:30:53 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -262,9 +262,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
262*/ 262*/
263static int l_strcmp (const TString *ls, const TString *rs) { 263static int l_strcmp (const TString *ls, const TString *rs) {
264 const char *l = getstr(ls); 264 const char *l = getstr(ls);
265 size_t ll = ls->tsv.len; 265 size_t ll = ls->len;
266 const char *r = getstr(rs); 266 const char *r = getstr(rs);
267 size_t lr = rs->tsv.len; 267 size_t lr = rs->len;
268 for (;;) { /* for each segment */ 268 for (;;) { /* for each segment */
269 int temp = strcoll(l, r); 269 int temp = strcoll(l, r);
270 if (temp != 0) /* not equal? */ 270 if (temp != 0) /* not equal? */
@@ -294,7 +294,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
294 else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */ 294 else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
295 return luai_numlt(nl, nr); 295 return luai_numlt(nl, nr);
296 else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ 296 else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
297 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; 297 return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
298 else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */ 298 else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */
299 luaG_ordererror(L, l, r); /* error */ 299 luaG_ordererror(L, l, r); /* error */
300 return res; 300 return res;
@@ -312,7 +312,7 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
312 else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */ 312 else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
313 return luai_numle(nl, nr); 313 return luai_numle(nl, nr);
314 else if (ttisstring(l) && ttisstring(r)) /* both are strings? */ 314 else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
315 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; 315 return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
316 else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ 316 else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
317 return res; 317 return res;
318 else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ 318 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) {
345 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ 345 case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
346 case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); 346 case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
347 case LUA_TLCF: return fvalue(t1) == fvalue(t2); 347 case LUA_TLCF: return fvalue(t1) == fvalue(t2);
348 case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); 348 case LUA_TSHRSTR: return eqshrstr(tsvalue(t1), tsvalue(t2));
349 case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); 349 case LUA_TLNGSTR: return luaS_eqlngstr(tsvalue(t1), tsvalue(t2));
350 case LUA_TUSERDATA: { 350 case LUA_TUSERDATA: {
351 if (uvalue(t1) == uvalue(t2)) return 1; 351 if (uvalue(t1) == uvalue(t2)) return 1;
352 else if (L == NULL) return 0; 352 else if (L == NULL) return 0;