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