summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lua/src/lstring.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lua/src/lstring.c')
-rw-r--r--3rdparty/lua/src/lstring.c135
1 files changed, 80 insertions, 55 deletions
diff --git a/3rdparty/lua/src/lstring.c b/3rdparty/lua/src/lstring.c
index 9351766fd63..13dcaf4259b 100644
--- a/3rdparty/lua/src/lstring.c
+++ b/3rdparty/lua/src/lstring.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.c,v 2.56 2015/11/23 11:32:51 roberto Exp $
+** $Id: lstring.c $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -22,16 +22,10 @@
#include "lstring.h"
-#define MEMERRMSG "not enough memory"
-
-
/*
-** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
-** compute its hash
+** Maximum size for string table.
*/
-#if !defined(LUAI_HASHLIMIT)
-#define LUAI_HASHLIMIT 5
-#endif
+#define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*))
/*
@@ -39,7 +33,7 @@
*/
int luaS_eqlngstr (TString *a, TString *b) {
size_t len = a->u.lnglen;
- lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
+ lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR);
return (a == b) || /* same instance or... */
((len == b->u.lnglen) && /* equal length and ... */
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
@@ -47,52 +41,65 @@ int luaS_eqlngstr (TString *a, TString *b) {
unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
- unsigned int h = seed ^ cast(unsigned int, l);
- size_t step = (l >> LUAI_HASHLIMIT) + 1;
- for (; l >= step; l -= step)
+ unsigned int h = seed ^ cast_uint(l);
+ for (; l > 0; l--)
h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1]));
return h;
}
unsigned int luaS_hashlongstr (TString *ts) {
- lua_assert(ts->tt == LUA_TLNGSTR);
+ lua_assert(ts->tt == LUA_VLNGSTR);
if (ts->extra == 0) { /* no hash? */
- ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash);
+ size_t len = ts->u.lnglen;
+ ts->hash = luaS_hash(getstr(ts), len, ts->hash);
ts->extra = 1; /* now it has its hash */
}
return ts->hash;
}
-/*
-** resizes the string table
-*/
-void luaS_resize (lua_State *L, int newsize) {
+static void tablerehash (TString **vect, int osize, int nsize) {
int i;
- stringtable *tb = &G(L)->strt;
- if (newsize > tb->size) { /* grow table if needed */
- luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
- for (i = tb->size; i < newsize; i++)
- tb->hash[i] = NULL;
- }
- for (i = 0; i < tb->size; i++) { /* rehash */
- TString *p = tb->hash[i];
- tb->hash[i] = NULL;
- while (p) { /* for each node in the list */
+ for (i = osize; i < nsize; i++) /* clear new elements */
+ vect[i] = NULL;
+ for (i = 0; i < osize; i++) { /* rehash old part of the array */
+ TString *p = vect[i];
+ vect[i] = NULL;
+ while (p) { /* for each string in the list */
TString *hnext = p->u.hnext; /* save next */
- unsigned int h = lmod(p->hash, newsize); /* new position */
- p->u.hnext = tb->hash[h]; /* chain it */
- tb->hash[h] = p;
+ unsigned int h = lmod(p->hash, nsize); /* new position */
+ p->u.hnext = vect[h]; /* chain it into array */
+ vect[h] = p;
p = hnext;
}
}
- if (newsize < tb->size) { /* shrink table if needed */
- /* vanishing slice should be empty */
- lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
- luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
+}
+
+
+/*
+** Resize the string table. If allocation fails, keep the current size.
+** (This can degrade performance, but any non-zero size should work
+** correctly.)
+*/
+void luaS_resize (lua_State *L, int nsize) {
+ stringtable *tb = &G(L)->strt;
+ int osize = tb->size;
+ TString **newvect;
+ if (nsize < osize) /* shrinking table? */
+ tablerehash(tb->hash, osize, nsize); /* depopulate shrinking part */
+ newvect = luaM_reallocvector(L, tb->hash, osize, nsize, TString*);
+ if (l_unlikely(newvect == NULL)) { /* reallocation failed? */
+ if (nsize < osize) /* was it shrinking table? */
+ tablerehash(tb->hash, nsize, osize); /* restore to original size */
+ /* leave table as it was */
+ }
+ else { /* allocation succeeded */
+ tb->hash = newvect;
+ tb->size = nsize;
+ if (nsize > osize)
+ tablerehash(newvect, osize, nsize); /* rehash for new size */
}
- tb->size = newsize;
}
@@ -104,8 +111,8 @@ void luaS_clearcache (global_State *g) {
int i, j;
for (i = 0; i < STRCACHE_N; i++)
for (j = 0; j < STRCACHE_M; j++) {
- if (iswhite(g->strcache[i][j])) /* will entry be collected? */
- g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */
+ if (iswhite(g->strcache[i][j])) /* will entry be collected? */
+ g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */
}
}
@@ -116,7 +123,10 @@ void luaS_clearcache (global_State *g) {
void luaS_init (lua_State *L) {
global_State *g = G(L);
int i, j;
- luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
+ stringtable *tb = &G(L)->strt;
+ tb->hash = luaM_newvector(L, MINSTRTABSIZE, TString*);
+ tablerehash(tb->hash, 0, MINSTRTABSIZE); /* clear array */
+ tb->size = MINSTRTABSIZE;
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
@@ -145,7 +155,7 @@ static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) {
TString *luaS_createlngstrobj (lua_State *L, size_t l) {
- TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed);
+ TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed);
ts->u.lnglen = l;
return ts;
}
@@ -161,34 +171,46 @@ void luaS_remove (lua_State *L, TString *ts) {
}
+static void growstrtab (lua_State *L, stringtable *tb) {
+ if (l_unlikely(tb->nuse == MAX_INT)) { /* too many strings? */
+ luaC_fullgc(L, 1); /* try to free some... */
+ if (tb->nuse == MAX_INT) /* still too many? */
+ luaM_error(L); /* cannot even create a message... */
+ }
+ if (tb->size <= MAXSTRTB / 2) /* can grow string table? */
+ luaS_resize(L, tb->size * 2);
+}
+
+
/*
-** checks whether short string exists and reuses it or creates a new one
+** Checks whether short string exists and reuses it or creates a new one.
*/
static TString *internshrstr (lua_State *L, const char *str, size_t l) {
TString *ts;
global_State *g = G(L);
+ stringtable *tb = &g->strt;
unsigned int h = luaS_hash(str, l, g->seed);
- TString **list = &g->strt.hash[lmod(h, g->strt.size)];
+ TString **list = &tb->hash[lmod(h, tb->size)];
lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */
for (ts = *list; ts != NULL; ts = ts->u.hnext) {
- if (l == ts->shrlen &&
- (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
+ if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
/* found! */
if (isdead(g, ts)) /* dead (but not collected yet)? */
changewhite(ts); /* resurrect it */
return ts;
}
}
- if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) {
- luaS_resize(L, g->strt.size * 2);
- list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
+ /* else must create a new string */
+ if (tb->nuse >= tb->size) { /* need to grow string table? */
+ growstrtab(L, tb);
+ list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */
}
- ts = createstrobj(L, l, LUA_TSHRSTR, h);
+ ts = createstrobj(L, l, LUA_VSHRSTR, h);
memcpy(getstr(ts), str, l * sizeof(char));
ts->shrlen = cast_byte(l);
ts->u.hnext = *list;
*list = ts;
- g->strt.nuse++;
+ tb->nuse++;
return ts;
}
@@ -201,7 +223,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
return internshrstr(L, str, l);
else {
TString *ts;
- if (l >= (MAX_SIZE - sizeof(TString))/sizeof(char))
+ if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char)))
luaM_toobig(L);
ts = luaS_createlngstrobj(L, l);
memcpy(getstr(ts), str, l * sizeof(char));
@@ -233,16 +255,19 @@ TString *luaS_new (lua_State *L, const char *str) {
}
-Udata *luaS_newudata (lua_State *L, size_t s) {
+Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue) {
Udata *u;
+ int i;
GCObject *o;
- if (s > MAX_SIZE - sizeof(Udata))
+ if (l_unlikely(s > MAX_SIZE - udatamemoffset(nuvalue)))
luaM_toobig(L);
- o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s));
+ o = luaC_newobj(L, LUA_VUSERDATA, sizeudata(nuvalue, s));
u = gco2u(o);
u->len = s;
+ u->nuvalue = nuvalue;
u->metatable = NULL;
- setuservalue(L, u, luaO_nilobject);
+ for (i = 0; i < nuvalue; i++)
+ setnilvalue(&u->uv[i].uv);
return u;
}