aboutsummaryrefslogtreecommitdiff
path: root/src/lua/lstring.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lua/lstring.c (renamed from src/lua-5.3/lstring.c)141
1 files changed, 89 insertions, 52 deletions
diff --git a/src/lua-5.3/lstring.c b/src/lua/lstring.c
index 6257f21..6f15747 100644
--- a/src/lua-5.3/lstring.c
+++ b/src/lua/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $ 2** $Id: lstring.c $
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*/
@@ -22,11 +22,8 @@
22#include "lstring.h" 22#include "lstring.h"
23 23
24 24
25#define MEMERRMSG "not enough memory"
26
27
28/* 25/*
29** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to 26** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a long string to
30** compute its hash 27** compute its hash
31*/ 28*/
32#if !defined(LUAI_HASHLIMIT) 29#if !defined(LUAI_HASHLIMIT)
@@ -34,21 +31,28 @@
34#endif 31#endif
35 32
36 33
34
35/*
36** Maximum size for string table.
37*/
38#define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*))
39
40
37/* 41/*
38** equality for long strings 42** equality for long strings
39*/ 43*/
40int luaS_eqlngstr (TString *a, TString *b) { 44int luaS_eqlngstr (TString *a, TString *b) {
41 size_t len = a->u.lnglen; 45 size_t len = a->u.lnglen;
42 lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); 46 lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR);
43 return (a == b) || /* same instance or... */ 47 return (a == b) || /* same instance or... */
44 ((len == b->u.lnglen) && /* equal length and ... */ 48 ((len == b->u.lnglen) && /* equal length and ... */
45 (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 49 (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
46} 50}
47 51
48 52
49unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { 53unsigned int luaS_hash (const char *str, size_t l, unsigned int seed,
50 unsigned int h = seed ^ cast(unsigned int, l); 54 size_t step) {
51 size_t step = (l >> LUAI_HASHLIMIT) + 1; 55 unsigned int h = seed ^ cast_uint(l);
52 for (; l >= step; l -= step) 56 for (; l >= step; l -= step)
53 h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); 57 h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1]));
54 return h; 58 return h;
@@ -56,43 +60,58 @@ unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
56 60
57 61
58unsigned int luaS_hashlongstr (TString *ts) { 62unsigned int luaS_hashlongstr (TString *ts) {
59 lua_assert(ts->tt == LUA_TLNGSTR); 63 lua_assert(ts->tt == LUA_VLNGSTR);
60 if (ts->extra == 0) { /* no hash? */ 64 if (ts->extra == 0) { /* no hash? */
61 ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash); 65 size_t len = ts->u.lnglen;
66 size_t step = (len >> LUAI_HASHLIMIT) + 1;
67 ts->hash = luaS_hash(getstr(ts), len, ts->hash, step);
62 ts->extra = 1; /* now it has its hash */ 68 ts->extra = 1; /* now it has its hash */
63 } 69 }
64 return ts->hash; 70 return ts->hash;
65} 71}
66 72
67 73
68/* 74static void tablerehash (TString **vect, int osize, int nsize) {
69** resizes the string table
70*/
71void luaS_resize (lua_State *L, int newsize) {
72 int i; 75 int i;
73 stringtable *tb = &G(L)->strt; 76 for (i = osize; i < nsize; i++) /* clear new elements */
74 if (newsize > tb->size) { /* grow table if needed */ 77 vect[i] = NULL;
75 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); 78 for (i = 0; i < osize; i++) { /* rehash old part of the array */
76 for (i = tb->size; i < newsize; i++) 79 TString *p = vect[i];
77 tb->hash[i] = NULL; 80 vect[i] = NULL;
78 } 81 while (p) { /* for each string in the list */
79 for (i = 0; i < tb->size; i++) { /* rehash */
80 TString *p = tb->hash[i];
81 tb->hash[i] = NULL;
82 while (p) { /* for each node in the list */
83 TString *hnext = p->u.hnext; /* save next */ 82 TString *hnext = p->u.hnext; /* save next */
84 unsigned int h = lmod(p->hash, newsize); /* new position */ 83 unsigned int h = lmod(p->hash, nsize); /* new position */
85 p->u.hnext = tb->hash[h]; /* chain it */ 84 p->u.hnext = vect[h]; /* chain it into array */
86 tb->hash[h] = p; 85 vect[h] = p;
87 p = hnext; 86 p = hnext;
88 } 87 }
89 } 88 }
90 if (newsize < tb->size) { /* shrink table if needed */ 89}
91 /* vanishing slice should be empty */ 90
92 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); 91
93 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); 92/*
93** Resize the string table. If allocation fails, keep the current size.
94** (This can degrade performance, but any non-zero size should work
95** correctly.)
96*/
97void luaS_resize (lua_State *L, int nsize) {
98 stringtable *tb = &G(L)->strt;
99 int osize = tb->size;
100 TString **newvect;
101 if (nsize < osize) /* shrinking table? */
102 tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */
103 newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*);
104 if (unlikely(newvect == NULL)) { /* reallocation failed? */
105 if (nsize < osize) /* was it shrinking table? */
106 tablerehash(tb->hash, nsize, osize); /* restore to original size */
107 /* leave table as it was */
108 }
109 else { /* allocation succeeded */
110 tb->hash = newvect;
111 tb->size = nsize;
112 if (nsize > osize)
113 tablerehash(newvect, osize, nsize); /* rehash for new size */
94 } 114 }
95 tb->size = newsize;
96} 115}
97 116
98 117
@@ -104,8 +123,8 @@ void luaS_clearcache (global_State *g) {
104 int i, j; 123 int i, j;
105 for (i = 0; i < STRCACHE_N; i++) 124 for (i = 0; i < STRCACHE_N; i++)
106 for (j = 0; j < STRCACHE_M; j++) { 125 for (j = 0; j < STRCACHE_M; j++) {
107 if (iswhite(g->strcache[i][j])) /* will entry be collected? */ 126 if (iswhite(g->strcache[i][j])) /* will entry be collected? */
108 g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */ 127 g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */
109 } 128 }
110} 129}
111 130
@@ -116,7 +135,10 @@ void luaS_clearcache (global_State *g) {
116void luaS_init (lua_State *L) { 135void luaS_init (lua_State *L) {
117 global_State *g = G(L); 136 global_State *g = G(L);
118 int i, j; 137 int i, j;
119 luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 138 stringtable *tb = &G(L)->strt;
139 tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*);
140 tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */
141 tb->size = MINSTRTABSIZE;
120 /* pre-create memory-error message */ 142 /* pre-create memory-error message */
121 g->memerrmsg = luaS_newliteral(L, MEMERRMSG); 143 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
122 luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ 144 luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
@@ -145,7 +167,7 @@ static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) {
145 167
146 168
147TString *luaS_createlngstrobj (lua_State *L, size_t l) { 169TString *luaS_createlngstrobj (lua_State *L, size_t l) {
148 TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed); 170 TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed);
149 ts->u.lnglen = l; 171 ts->u.lnglen = l;
150 return ts; 172 return ts;
151} 173}
@@ -161,34 +183,46 @@ void luaS_remove (lua_State *L, TString *ts) {
161} 183}
162 184
163 185
186static void growstrtab (lua_State *L, stringtable *tb) {
187 if (unlikely(tb->nuse == MAX_INT)) { /* too many strings? */
188 luaC_fullgc(L, 1); /* try to free some... */
189 if (tb->nuse == MAX_INT) /* still too many? */
190 luaM_error(L); /* cannot even create a message... */
191 }
192 if (tb->size <= MAXSTRTB / 2) /* can grow string table? */
193 luaS_resize(L, tb->size * 2);
194}
195
196
164/* 197/*
165** checks whether short string exists and reuses it or creates a new one 198** Checks whether short string exists and reuses it or creates a new one.
166*/ 199*/
167static TString *internshrstr (lua_State *L, const char *str, size_t l) { 200static TString *internshrstr (lua_State *L, const char *str, size_t l) {
168 TString *ts; 201 TString *ts;
169 global_State *g = G(L); 202 global_State *g = G(L);
170 unsigned int h = luaS_hash(str, l, g->seed); 203 stringtable *tb = &g->strt;
171 TString **list = &g->strt.hash[lmod(h, g->strt.size)]; 204 unsigned int h = luaS_hash(str, l, g->seed, 1);
205 TString **list = &tb->hash[lmod(h, tb->size)];
172 lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ 206 lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */
173 for (ts = *list; ts != NULL; ts = ts->u.hnext) { 207 for (ts = *list; ts != NULL; ts = ts->u.hnext) {
174 if (l == ts->shrlen && 208 if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
175 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
176 /* found! */ 209 /* found! */
177 if (isdead(g, ts)) /* dead (but not collected yet)? */ 210 if (isdead(g, ts)) /* dead (but not collected yet)? */
178 changewhite(ts); /* resurrect it */ 211 changewhite(ts); /* resurrect it */
179 return ts; 212 return ts;
180 } 213 }
181 } 214 }
182 if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) { 215 /* else must create a new string */
183 luaS_resize(L, g->strt.size * 2); 216 if (tb->nuse >= tb->size) { /* need to grow string table? */
184 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ 217 growstrtab(L, tb);
218 list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */
185 } 219 }
186 ts = createstrobj(L, l, LUA_TSHRSTR, h); 220 ts = createstrobj(L, l, LUA_VSHRSTR, h);
187 memcpy(getstr(ts), str, l * sizeof(char)); 221 memcpy(getstr(ts), str, l * sizeof(char));
188 ts->shrlen = cast_byte(l); 222 ts->shrlen = cast_byte(l);
189 ts->u.hnext = *list; 223 ts->u.hnext = *list;
190 *list = ts; 224 *list = ts;
191 g->strt.nuse++; 225 tb->nuse++;
192 return ts; 226 return ts;
193} 227}
194 228
@@ -201,7 +235,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
201 return internshrstr(L, str, l); 235 return internshrstr(L, str, l);
202 else { 236 else {
203 TString *ts; 237 TString *ts;
204 if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char)) 238 if (unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char)))
205 luaM_toobig(L); 239 luaM_toobig(L);
206 ts = luaS_createlngstrobj(L, l); 240 ts = luaS_createlngstrobj(L, l);
207 memcpy(getstr(ts), str, l * sizeof(char)); 241 memcpy(getstr(ts), str, l * sizeof(char));
@@ -233,16 +267,19 @@ TString *luaS_new (lua_State *L, const char *str) {
233} 267}
234 268
235 269
236Udata *luaS_newudata (lua_State *L, size_t s) { 270Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) {
237 Udata *u; 271 Udata *u;
272 int i;
238 GCObject *o; 273 GCObject *o;
239 if (s > MAX_SIZE - sizeof(Udata)) 274 if (unlikely(s > MAX_SIZE - udatamemoffset(nuvalue)))
240 luaM_toobig(L); 275 luaM_toobig(L);
241 o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s)); 276 o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s));
242 u = gco2u(o); 277 u = gco2u(o);
243 u->len = s; 278 u->len = s;
279 u->nuvalue = nuvalue;
244 u->metatable = NULL; 280 u->metatable = NULL;
245 setuservalue(L, u, luaO_nilobject); 281 for (i = 0; i < nuvalue; i++)
282 setnilvalue(&u->uv[i].uv);
246 return u; 283 return u;
247} 284}
248 285