aboutsummaryrefslogtreecommitdiff
path: root/lstring.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-01 14:40:29 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2017-12-01 14:40:29 -0200
commit9d28b401527ccb41f544d431abe52da69e8beb3c (patch)
treef079b0259179b3b1e5c0f9cc531a6b5b833da7a7 /lstring.c
parente0bece77d6ee926de4ab3108b0fa84f03ff759d4 (diff)
downloadlua-9d28b401527ccb41f544d431abe52da69e8beb3c.tar.gz
lua-9d28b401527ccb41f544d431abe52da69e8beb3c.tar.bz2
lua-9d28b401527ccb41f544d431abe52da69e8beb3c.zip
rehashes string table always allocating a new array instead of
reallocating old one. (Avoids problems if reallocation to a small size fails.)
Diffstat (limited to 'lstring.c')
-rw-r--r--lstring.c28
1 files changed, 11 insertions, 17 deletions
diff --git a/lstring.c b/lstring.c
index a851fd74..e8f6f5c9 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.56 2015/11/23 11:32:51 roberto Exp roberto $ 2** $Id: lstring.c,v 2.57 2017/07/27 13:50:16 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*/
@@ -63,32 +63,26 @@ unsigned int luaS_hashlongstr (TString *ts) {
63 63
64 64
65/* 65/*
66** resizes the string table 66** Resizes the string table.
67*/ 67*/
68void luaS_resize (lua_State *L, int newsize) { 68void luaS_resize (lua_State *L, int newsize) {
69 int i; 69 int i;
70 TString **newhash = luaM_newvector(L, newsize, TString *);
70 stringtable *tb = &G(L)->strt; 71 stringtable *tb = &G(L)->strt;
71 if (newsize > tb->size) { /* grow table if needed */ 72 for (i = 0; i < newsize; i++) /* initialize new hash array */
72 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); 73 newhash[i] = NULL;
73 for (i = tb->size; i < newsize; i++) 74 for (i = 0; i < tb->size; i++) { /* rehash all elements into new array */
74 tb->hash[i] = NULL;
75 }
76 for (i = 0; i < tb->size; i++) { /* rehash */
77 TString *p = tb->hash[i]; 75 TString *p = tb->hash[i];
78 tb->hash[i] = NULL; 76 while (p) { /* for each string in the list */
79 while (p) { /* for each node in the list */
80 TString *hnext = p->u.hnext; /* save next */ 77 TString *hnext = p->u.hnext; /* save next */
81 unsigned int h = lmod(p->hash, newsize); /* new position */ 78 unsigned int h = lmod(p->hash, newsize); /* new position */
82 p->u.hnext = tb->hash[h]; /* chain it */ 79 p->u.hnext = newhash[h]; /* chain it into new array */
83 tb->hash[h] = p; 80 newhash[h] = p;
84 p = hnext; 81 p = hnext;
85 } 82 }
86 } 83 }
87 if (newsize < tb->size) { /* shrink table if needed */ 84 luaM_freearray(L, tb->hash, tb->size); /* free old array */
88 /* vanishing slice should be empty */ 85 tb->hash = newhash;
89 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
90 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
91 }
92 tb->size = newsize; 86 tb->size = newsize;
93} 87}
94 88