diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-07-18 10:36:14 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-07-18 10:36:14 -0300 |
commit | ca41b43f53562e64abe433d6346d174c92548603 (patch) | |
tree | 03f7a99f76359fc1e0bbc45fc13e579ff2aafabb | |
parent | 3511e186cde4b78f268d17199d0f46fb3eaa9638 (diff) | |
download | lua-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.c | 6 | ||||
-rw-r--r-- | lgc.c | 13 | ||||
-rw-r--r-- | llex.c | 12 | ||||
-rw-r--r-- | lobject.h | 43 | ||||
-rw-r--r-- | lparser.c | 8 | ||||
-rw-r--r-- | lstate.c | 4 | ||||
-rw-r--r-- | lstate.h | 14 | ||||
-rw-r--r-- | lstring.c | 44 | ||||
-rw-r--r-- | lstring.h | 9 | ||||
-rw-r--r-- | ltable.c | 22 | ||||
-rw-r--r-- | ltests.c | 13 | ||||
-rw-r--r-- | ltm.c | 4 | ||||
-rw-r--r-- | lvm.c | 14 |
13 files changed, 102 insertions, 104 deletions
@@ -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); |
@@ -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 | |||
89 | static void reallymarkobject (global_State *g, GCObject *o); | 86 | static 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))); |
@@ -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) { | |||
67 | void luaX_init (lua_State *L) { | 67 | void 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 | } |
@@ -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 | */ |
303 | typedef union TString { | 303 | typedef 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 | */ | ||
315 | typedef 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 | /* |
@@ -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; |
@@ -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); |
@@ -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 | */ |
175 | union GCUnion { | 175 | union 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) |
@@ -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 | */ |
36 | int luaS_eqlngstr (TString *a, TString *b) { | 36 | int 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 | ||
107 | void luaS_remove (lua_State *L, TString *ts) { | 107 | void 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; |
@@ -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 | ||
35 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); | 36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); |
@@ -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 | */ |
502 | const TValue *luaH_getstr (Table *t, TString *key) { | 502 | const 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 | */ |
521 | const TValue *luaH_get (Table *t, const TValue *key) { | 521 | const 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: { |
@@ -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 | ||
217 | static void checkvalref (global_State *g, GCObject *f, const TValue *t) { | 214 | static 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++; |
@@ -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 | ||
@@ -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 | */ |
263 | static int l_strcmp (const TString *ls, const TString *rs) { | 263 | static 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; |