diff options
| -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)++; |
