diff options
Diffstat (limited to 'ltable.c')
-rw-r--r-- | ltable.c | 24 |
1 files changed, 14 insertions, 10 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.131 2003/03/24 14:18:42 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.132 2003/04/03 13:35:34 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 | */ |
@@ -45,9 +45,7 @@ | |||
45 | #define MAXBITS (BITS_INT-2) | 45 | #define MAXBITS (BITS_INT-2) |
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | /* check whether `x' < 2^MAXBITS */ | 48 | #define MAXASIZE (1 << MAXBITS) |
49 | #define toobig(x) ((((x)-1) >> MAXBITS) != 0) | ||
50 | |||
51 | 49 | ||
52 | /* function to convert a lua_Number to int (with any rounding method) */ | 50 | /* function to convert a lua_Number to int (with any rounding method) */ |
53 | #ifndef lua_number2int | 51 | #ifndef lua_number2int |
@@ -116,11 +114,13 @@ Node *luaH_mainposition (const Table *t, const TObject *key) { | |||
116 | ** returns the index for `key' if `key' is an appropriate key to live in | 114 | ** returns the index for `key' if `key' is an appropriate key to live in |
117 | ** the array part of the table, -1 otherwise. | 115 | ** the array part of the table, -1 otherwise. |
118 | */ | 116 | */ |
119 | static int arrayindex (const TObject *key) { | 117 | static int arrayindex (const TObject *key, lua_Number lim) { |
120 | if (ttisnumber(key)) { | 118 | if (ttisnumber(key)) { |
119 | lua_Number n = nvalue(key); | ||
121 | int k; | 120 | int k; |
122 | lua_number2int(k, (nvalue(key))); | 121 | if (n <= 0 || n > lim) return -1; /* out of range? */ |
123 | if (cast(lua_Number, k) == nvalue(key) && k >= 1 && !toobig(k)) | 122 | lua_number2int(k, n); |
123 | if (cast(lua_Number, k) == nvalue(key)) | ||
124 | return k; | 124 | return k; |
125 | } | 125 | } |
126 | return -1; /* `key' did not match some condition */ | 126 | return -1; /* `key' did not match some condition */ |
@@ -135,8 +135,8 @@ static int arrayindex (const TObject *key) { | |||
135 | static int luaH_index (lua_State *L, Table *t, StkId key) { | 135 | static int luaH_index (lua_State *L, Table *t, StkId key) { |
136 | int i; | 136 | int i; |
137 | if (ttisnil(key)) return -1; /* first iteration */ | 137 | if (ttisnil(key)) return -1; /* first iteration */ |
138 | i = arrayindex(key); | 138 | i = arrayindex(key, t->sizearray); |
139 | if (0 <= i && i <= t->sizearray) { /* is `key' inside array part? */ | 139 | if (0 <= i) { /* is `key' inside array part? */ |
140 | return i-1; /* yes; that's the index (corrected to C) */ | 140 | return i-1; /* yes; that's the index (corrected to C) */ |
141 | } | 141 | } |
142 | else { | 142 | else { |
@@ -202,6 +202,7 @@ static void numuse (const Table *t, int *narray, int *nhash) { | |||
202 | int nums[MAXBITS+1]; | 202 | int nums[MAXBITS+1]; |
203 | int i, lg; | 203 | int i, lg; |
204 | int totaluse = 0; | 204 | int totaluse = 0; |
205 | lua_Number sizelimit; /* an upper bound for the array size */ | ||
205 | /* count elements in array part */ | 206 | /* count elements in array part */ |
206 | for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */ | 207 | for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */ |
207 | int ttlg = twoto(lg); /* 2^lg */ | 208 | int ttlg = twoto(lg); /* 2^lg */ |
@@ -221,10 +222,13 @@ static void numuse (const Table *t, int *narray, int *nhash) { | |||
221 | *narray = totaluse; /* all previous uses were in array part */ | 222 | *narray = totaluse; /* all previous uses were in array part */ |
222 | /* count elements in hash part */ | 223 | /* count elements in hash part */ |
223 | i = sizenode(t); | 224 | i = sizenode(t); |
225 | /* array part cannot be larger than twice the maximum number of elements */ | ||
226 | sizelimit = cast(lua_Number, totaluse + i) * 2; | ||
227 | if (sizelimit >= MAXASIZE) sizelimit = MAXASIZE; | ||
224 | while (i--) { | 228 | while (i--) { |
225 | Node *n = &t->node[i]; | 229 | Node *n = &t->node[i]; |
226 | if (!ttisnil(gval(n))) { | 230 | if (!ttisnil(gval(n))) { |
227 | int k = arrayindex(gkey(n)); | 231 | int k = arrayindex(gkey(n), sizelimit); |
228 | if (k >= 0) { /* is `key' an appropriate array index? */ | 232 | if (k >= 0) { /* is `key' an appropriate array index? */ |
229 | nums[luaO_log2(k-1)+1]++; /* count as such */ | 233 | nums[luaO_log2(k-1)+1]++; /* count as such */ |
230 | (*narray)++; | 234 | (*narray)++; |