00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <math.h>
00022 #include <string.h>
00023
00024 #define ltable_c
00025 #define LUA_CORE
00026
00027 #include "lua.h"
00028
00029 #include "ldebug.h"
00030 #include "ldo.h"
00031 #include "lgc.h"
00032 #include "lmem.h"
00033 #include "lobject.h"
00034 #include "lstate.h"
00035 #include "ltable.h"
00036
00037
00038
00039
00040
00041 #if LUAI_BITSINT > 26
00042 #define MAXBITS 26
00043 #else
00044 #define MAXBITS (LUAI_BITSINT-2)
00045 #endif
00046
00047 #define MAXASIZE (1 << MAXBITS)
00048
00049
00050 #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
00051
00052 #define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
00053 #define hashboolean(t,p) hashpow2(t, p)
00054
00055
00056
00057
00058
00059
00060 #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
00061
00062
00063 #define hashpointer(t,p) hashmod(t, IntPoint(p))
00064
00065
00066
00067
00068
00069 #define numints cast_int(sizeof(lua_Number)/sizeof(int))
00070
00071
00072
00073 #define dummynode (&dummynode_)
00074
00075 static Node dummynode_ = {
00076 {{NULL}, LUA_TNIL},
00077 {{{NULL}, LUA_TNIL, NULL}}
00078 };
00079
00080
00081
00082
00083
00084 static Node *hashnum (const Table *t, lua_Number n) {
00085 unsigned int a[numints];
00086 int i;
00087 if (luai_numeq(n, 0))
00088 return gnode(t, 0);
00089 memcpy(a, &n, sizeof(a));
00090 for (i = 1; i < numints; i++) a[0] += a[i];
00091 return hashmod(t, a[0]);
00092 }
00093
00094
00095
00096
00097
00098
00099
00100 static Node *mainposition (const Table *t, const TValue *key) {
00101 switch (ttype(key)) {
00102 case LUA_TNUMBER:
00103 return hashnum(t, nvalue(key));
00104 case LUA_TSTRING:
00105 return hashstr(t, rawtsvalue(key));
00106 case LUA_TBOOLEAN:
00107 return hashboolean(t, bvalue(key));
00108 case LUA_TLIGHTUSERDATA:
00109 return hashpointer(t, pvalue(key));
00110 default:
00111 return hashpointer(t, gcvalue(key));
00112 }
00113 }
00114
00115
00116
00117
00118
00119
00120 static int arrayindex (const TValue *key) {
00121 if (ttisnumber(key)) {
00122 lua_Number n = nvalue(key);
00123 int k;
00124 lua_number2int(k, n);
00125 if (luai_numeq(cast_num(k), n))
00126 return k;
00127 }
00128 return -1;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 static int findindex (lua_State *L, Table *t, StkId key) {
00138 int i;
00139 if (ttisnil(key)) return -1;
00140 i = arrayindex(key);
00141 if (0 < i && i <= t->sizearray)
00142 return i-1;
00143 else {
00144 Node *n = mainposition(t, key);
00145 do {
00146
00147 if (luaO_rawequalObj(key2tval(n), key) ||
00148 (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
00149 gcvalue(gkey(n)) == gcvalue(key))) {
00150 i = cast_int(n - gnode(t, 0));
00151
00152 return i + t->sizearray;
00153 }
00154 else n = gnext(n);
00155 } while (n);
00156 luaG_runerror(L, "invalid key to " LUA_QL("next"));
00157 return 0;
00158 }
00159 }
00160
00161
00162 int luaH_next (lua_State *L, Table *t, StkId key) {
00163 int i = findindex(L, t, key);
00164 for (i++; i < t->sizearray; i++) {
00165 if (!ttisnil(&t->array[i])) {
00166 setnvalue(key, cast_num(i+1));
00167 setobj2s(L, key+1, &t->array[i]);
00168 return 1;
00169 }
00170 }
00171 for (i -= t->sizearray; i < sizenode(t); i++) {
00172 if (!ttisnil(gval(gnode(t, i)))) {
00173 setobj2s(L, key, key2tval(gnode(t, i)));
00174 setobj2s(L, key+1, gval(gnode(t, i)));
00175 return 1;
00176 }
00177 }
00178 return 0;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 static int computesizes (int nums[], int *narray) {
00190 int i;
00191 int twotoi;
00192 int a = 0;
00193 int na = 0;
00194 int n = 0;
00195 for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
00196 if (nums[i] > 0) {
00197 a += nums[i];
00198 if (a > twotoi/2) {
00199 n = twotoi;
00200 na = a;
00201 }
00202 }
00203 if (a == *narray) break;
00204 }
00205 *narray = n;
00206 lua_assert(*narray/2 <= na && na <= *narray);
00207 return na;
00208 }
00209
00210
00211 static int countint (const TValue *key, int *nums) {
00212 int k = arrayindex(key);
00213 if (0 < k && k <= MAXASIZE) {
00214 nums[ceillog2(k)]++;
00215 return 1;
00216 }
00217 else
00218 return 0;
00219 }
00220
00221
00222 static int numusearray (const Table *t, int *nums) {
00223 int lg;
00224 int ttlg;
00225 int ause = 0;
00226 int i = 1;
00227 for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) {
00228 int lc = 0;
00229 int lim = ttlg;
00230 if (lim > t->sizearray) {
00231 lim = t->sizearray;
00232 if (i > lim)
00233 break;
00234 }
00235
00236 for (; i <= lim; i++) {
00237 if (!ttisnil(&t->array[i-1]))
00238 lc++;
00239 }
00240 nums[lg] += lc;
00241 ause += lc;
00242 }
00243 return ause;
00244 }
00245
00246
00247 static int numusehash (const Table *t, int *nums, int *pnasize) {
00248 int totaluse = 0;
00249 int ause = 0;
00250 int i = sizenode(t);
00251 while (i--) {
00252 Node *n = &t->node[i];
00253 if (!ttisnil(gval(n))) {
00254 ause += countint(key2tval(n), nums);
00255 totaluse++;
00256 }
00257 }
00258 *pnasize += ause;
00259 return totaluse;
00260 }
00261
00262
00263 static void setarrayvector (lua_State *L, Table *t, int size) {
00264 int i;
00265 luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
00266 for (i=t->sizearray; i<size; i++)
00267 setnilvalue(&t->array[i]);
00268 t->sizearray = size;
00269 }
00270
00271
00272 static void setnodevector (lua_State *L, Table *t, int size) {
00273 int lsize;
00274 if (size == 0) {
00275 t->node = cast(Node *, dummynode);
00276 lsize = 0;
00277 }
00278 else {
00279 int i;
00280 lsize = ceillog2(size);
00281 if (lsize > MAXBITS)
00282 luaG_runerror(L, "table overflow");
00283 size = twoto(lsize);
00284 t->node = luaM_newvector(L, size, Node);
00285 for (i=0; i<size; i++) {
00286 Node *n = gnode(t, i);
00287 gnext(n) = NULL;
00288 setnilvalue(gkey(n));
00289 setnilvalue(gval(n));
00290 }
00291 }
00292 t->lsizenode = cast_byte(lsize);
00293 t->lastfree = gnode(t, size);
00294 }
00295
00296
00297 static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
00298 int i;
00299 int oldasize = t->sizearray;
00300 int oldhsize = t->lsizenode;
00301 Node *nold = t->node;
00302 if (nasize > oldasize)
00303 setarrayvector(L, t, nasize);
00304
00305 setnodevector(L, t, nhsize);
00306 if (nasize < oldasize) {
00307 t->sizearray = nasize;
00308
00309 for (i=nasize; i<oldasize; i++) {
00310 if (!ttisnil(&t->array[i]))
00311 setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
00312 }
00313
00314 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
00315 }
00316
00317 for (i = twoto(oldhsize) - 1; i >= 0; i--) {
00318 Node *old = nold+i;
00319 if (!ttisnil(gval(old)))
00320 setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
00321 }
00322 if (nold != dummynode)
00323 luaM_freearray(L, nold, twoto(oldhsize), Node);
00324 }
00325
00326
00327 void luaH_resizearray (lua_State *L, Table *t, int nasize) {
00328 int nsize = (t->node == dummynode) ? 0 : sizenode(t);
00329 resize(L, t, nasize, nsize);
00330 }
00331
00332
00333 static void rehash (lua_State *L, Table *t, const TValue *ek) {
00334 int nasize, na;
00335 int nums[MAXBITS+1];
00336 int i;
00337 int totaluse;
00338 for (i=0; i<=MAXBITS; i++) nums[i] = 0;
00339 nasize = numusearray(t, nums);
00340 totaluse = nasize;
00341 totaluse += numusehash(t, nums, &nasize);
00342
00343 nasize += countint(ek, nums);
00344 totaluse++;
00345
00346 na = computesizes(nums, &nasize);
00347
00348 resize(L, t, nasize, totaluse - na);
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358 Table *luaH_new (lua_State *L, int narray, int nhash) {
00359 Table *t = luaM_new(L, Table);
00360 luaC_link(L, obj2gco(t), LUA_TTABLE);
00361 t->metatable = NULL;
00362 t->flags = cast_byte(~0);
00363
00364 t->array = NULL;
00365 t->sizearray = 0;
00366 t->lsizenode = 0;
00367 t->node = cast(Node *, dummynode);
00368 setarrayvector(L, t, narray);
00369 setnodevector(L, t, nhash);
00370 return t;
00371 }
00372
00373
00374 void luaH_free (lua_State *L, Table *t) {
00375 if (t->node != dummynode)
00376 luaM_freearray(L, t->node, sizenode(t), Node);
00377 luaM_freearray(L, t->array, t->sizearray, TValue);
00378 luaM_free(L, t);
00379 }
00380
00381
00382 static Node *getfreepos (Table *t) {
00383 while (t->lastfree-- > t->node) {
00384 if (ttisnil(gkey(t->lastfree)))
00385 return t->lastfree;
00386 }
00387 return NULL;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
00400 Node *mp = mainposition(t, key);
00401 if (!ttisnil(gval(mp)) || mp == dummynode) {
00402 Node *othern;
00403 Node *n = getfreepos(t);
00404 if (n == NULL) {
00405 rehash(L, t, key);
00406 return luaH_set(L, t, key);
00407 }
00408 lua_assert(n != dummynode);
00409 othern = mainposition(t, key2tval(mp));
00410 if (othern != mp) {
00411
00412 while (gnext(othern) != mp) othern = gnext(othern);
00413 gnext(othern) = n;
00414 *n = *mp;
00415 gnext(mp) = NULL;
00416 setnilvalue(gval(mp));
00417 }
00418 else {
00419
00420 gnext(n) = gnext(mp);
00421 gnext(mp) = n;
00422 mp = n;
00423 }
00424 }
00425 gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
00426 luaC_barriert(L, t, key);
00427 lua_assert(ttisnil(gval(mp)));
00428 return gval(mp);
00429 }
00430
00431
00432
00433
00434
00435 TValue *luaH_getnum (Table *t, int key) {
00436
00437 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
00438 return &t->array[key-1];
00439 else {
00440 lua_Number nk = cast_num(key);
00441 Node *n = hashnum(t, nk);
00442 do {
00443 if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
00444 return gval(n);
00445 else n = gnext(n);
00446 } while (n);
00447 return luaO_nilobject;
00448 }
00449 }
00450
00451
00452
00453
00454
00455 TValue *luaH_getstr (Table *t, TString *key) {
00456 Node *n = hashstr(t, key);
00457 do {
00458 if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
00459 return gval(n);
00460 else n = gnext(n);
00461 } while (n);
00462 return luaO_nilobject;
00463 }
00464
00465
00466
00467
00468
00469 TValue *luaH_get (Table *t, const TValue *key) {
00470 switch (ttype(key)) {
00471 case LUA_TNIL: return luaO_nilobject;
00472 case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
00473 case LUA_TNUMBER: {
00474 int k;
00475 lua_Number n = nvalue(key);
00476 lua_number2int(k, n);
00477 if (luai_numeq(cast_num(k), nvalue(key)))
00478 return luaH_getnum(t, k);
00479
00480 }
00481 default: {
00482 Node *n = mainposition(t, key);
00483 do {
00484 if (luaO_rawequalObj(key2tval(n), key))
00485 return gval(n);
00486 else n = gnext(n);
00487 } while (n);
00488 return luaO_nilobject;
00489 }
00490 }
00491 }
00492
00493
00494 TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
00495 TValue *p = luaH_get(t, key);
00496 t->flags = 0;
00497 if (p != luaO_nilobject)
00498 return cast(TValue *, p);
00499 else {
00500 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
00501 else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
00502 luaG_runerror(L, "table index is NaN");
00503 return newkey(L, t, key);
00504 }
00505 }
00506
00507
00508 TValue *luaH_setnum (lua_State *L, Table *t, int key) {
00509 TValue *p = luaH_getnum(t, key);
00510 if (p != luaO_nilobject)
00511 return cast(TValue *, p);
00512 else {
00513 TValue k;
00514 setnvalue(&k, cast_num(key));
00515 return newkey(L, t, &k);
00516 }
00517 }
00518
00519
00520 TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
00521 TValue *p = luaH_getstr(t, key);
00522 if (p != luaO_nilobject)
00523 return cast(TValue *, p);
00524 else {
00525 TValue k;
00526 setsvalue(L, &k, key);
00527 return newkey(L, t, &k);
00528 }
00529 }
00530
00531
00532 static int unbound_search (Table *t, unsigned int j) {
00533 unsigned int i = j;
00534 j++;
00535
00536 while (!ttisnil(luaH_getnum(t, j))) {
00537 i = j;
00538 j *= 2;
00539 if (j > cast(unsigned int, MAX_INT)) {
00540
00541 i = 1;
00542 while (!ttisnil(luaH_getnum(t, i))) i++;
00543 return i - 1;
00544 }
00545 }
00546
00547 while (j - i > 1) {
00548 unsigned int m = (i+j)/2;
00549 if (ttisnil(luaH_getnum(t, m))) j = m;
00550 else i = m;
00551 }
00552 return i;
00553 }
00554
00555
00556
00557
00558
00559
00560 int luaH_getn (Table *t) {
00561 unsigned int j = t->sizearray;
00562 if (j > 0 && ttisnil(&t->array[j - 1])) {
00563
00564 unsigned int i = 0;
00565 while (j - i > 1) {
00566 unsigned int m = (i+j)/2;
00567 if (ttisnil(&t->array[m - 1])) j = m;
00568 else i = m;
00569 }
00570 return i;
00571 }
00572
00573 else if (t->node == dummynode)
00574 return j;
00575 else return unbound_search(t, j);
00576 }
00577
00578
00579
00580 #if defined(LUA_DEBUG)
00581
00582 Node *luaH_mainposition (const Table *t, const TValue *key) {
00583 return mainposition(t, key);
00584 }
00585
00586 int luaH_isdummy (Node *n) { return n == dummynode; }
00587
00588 #endif