aboutsummaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/ltable.c b/ltable.c
index 8c971b27..7147f6fe 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.71 2012/05/23 15:37:09 roberto Exp roberto $ 2** $Id: ltable.c,v 2.71 2012/05/23 15:37:09 roberto Exp $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -52,6 +52,7 @@
52 52
53#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) 53#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
54#define hashboolean(t,p) hashpow2(t, p) 54#define hashboolean(t,p) hashpow2(t, p)
55#define hashint(t,i) hashpow2(t, i)
55 56
56 57
57/* 58/*
@@ -96,8 +97,12 @@ static Node *hashnum (const Table *t, lua_Number n) {
96*/ 97*/
97static Node *mainposition (const Table *t, const TValue *key) { 98static Node *mainposition (const Table *t, const TValue *key) {
98 switch (ttype(key)) { 99 switch (ttype(key)) {
99 case LUA_TNUMBER: 100 case LUA_TNUMINT:
100 return hashnum(t, nvalue(key)); 101 return hashint(t, ivalue(key));
102 case LUA_TNUMFLT:
103 return hashnum(t, fltvalue(key));
104 case LUA_TSHRSTR:
105 return hashstr(t, rawtsvalue(key));
101 case LUA_TLNGSTR: { 106 case LUA_TLNGSTR: {
102 TString *s = rawtsvalue(key); 107 TString *s = rawtsvalue(key);
103 if (s->tsv.extra == 0) { /* no hash? */ 108 if (s->tsv.extra == 0) { /* no hash? */
@@ -106,8 +111,6 @@ static Node *mainposition (const Table *t, const TValue *key) {
106 } 111 }
107 return hashstr(t, rawtsvalue(key)); 112 return hashstr(t, rawtsvalue(key));
108 } 113 }
109 case LUA_TSHRSTR:
110 return hashstr(t, rawtsvalue(key));
111 case LUA_TBOOLEAN: 114 case LUA_TBOOLEAN:
112 return hashboolean(t, bvalue(key)); 115 return hashboolean(t, bvalue(key));
113 case LUA_TLIGHTUSERDATA: 116 case LUA_TLIGHTUSERDATA:
@@ -120,19 +123,24 @@ static Node *mainposition (const Table *t, const TValue *key) {
120} 123}
121 124
122 125
126static int numisint (lua_Number n, int *p) {
127 int k;
128 lua_number2int(k, n);
129 if (luai_numeq(cast_num(k), n)) { /* 'k' is int? */
130 *p = k;
131 return 1;
132 }
133 return 0;
134}
135
136
123/* 137/*
124** returns the index for `key' if `key' is an appropriate key to live in 138** returns the index for `key' if `key' is an appropriate key to live in
125** the array part of the table, -1 otherwise. 139** the array part of the table, -1 otherwise.
126*/ 140*/
127static int arrayindex (const TValue *key) { 141static int arrayindex (const TValue *key) {
128 if (ttisnumber(key)) { 142 if (ttisinteger(key)) return ivalue(key);
129 lua_Number n = nvalue(key); 143 else return -1; /* `key' did not match some condition */
130 int k;
131 lua_number2int(k, n);
132 if (luai_numeq(cast_num(k), n))
133 return k;
134 }
135 return -1; /* `key' did not match some condition */
136} 144}
137 145
138 146
@@ -170,7 +178,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
170 int i = findindex(L, t, key); /* find original element */ 178 int i = findindex(L, t, key); /* find original element */
171 for (i++; i < t->sizearray; i++) { /* try first array part */ 179 for (i++; i < t->sizearray; i++) { /* try first array part */
172 if (!ttisnil(&t->array[i])) { /* a non-nil value? */ 180 if (!ttisnil(&t->array[i])) { /* a non-nil value? */
173 setnvalue(key, cast_num(i+1)); 181 setivalue(key, i + 1);
174 setobj2s(L, key+1, &t->array[i]); 182 setobj2s(L, key+1, &t->array[i]);
175 return 1; 183 return 1;
176 } 184 }
@@ -404,9 +412,18 @@ static Node *getfreepos (Table *t) {
404*/ 412*/
405TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { 413TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
406 Node *mp; 414 Node *mp;
415 TValue aux;
407 if (ttisnil(key)) luaG_runerror(L, "table index is nil"); 416 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
408 else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) 417 else if (ttisfloat(key)) {
409 luaG_runerror(L, "table index is NaN"); 418 lua_Number n = fltvalue(key);
419 int k;
420 if (luai_numisnan(L, n))
421 luaG_runerror(L, "table index is NaN");
422 if (numisint(n, &k)) { /* index is int? */
423 setivalue(&aux, k);
424 key = &aux; /* insert it as an integer */
425 }
426 }
410 mp = mainposition(t, key); 427 mp = mainposition(t, key);
411 if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ 428 if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
412 Node *othern; 429 Node *othern;
@@ -448,10 +465,9 @@ const TValue *luaH_getint (Table *t, int key) {
448 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) 465 if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
449 return &t->array[key-1]; 466 return &t->array[key-1];
450 else { 467 else {
451 lua_Number nk = cast_num(key); 468 Node *n = hashint(t, key);
452 Node *n = hashnum(t, nk);
453 do { /* check whether `key' is somewhere in the chain */ 469 do { /* check whether `key' is somewhere in the chain */
454 if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) 470 if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
455 return gval(n); /* that's it */ 471 return gval(n); /* that's it */
456 else n = gnext(n); 472 else n = gnext(n);
457 } while (n); 473 } while (n);
@@ -481,12 +497,11 @@ const TValue *luaH_getstr (Table *t, TString *key) {
481const TValue *luaH_get (Table *t, const TValue *key) { 497const TValue *luaH_get (Table *t, const TValue *key) {
482 switch (ttype(key)) { 498 switch (ttype(key)) {
483 case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); 499 case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
500 case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
484 case LUA_TNIL: return luaO_nilobject; 501 case LUA_TNIL: return luaO_nilobject;
485 case LUA_TNUMBER: { 502 case LUA_TNUMFLT: {
486 int k; 503 int k;
487 lua_Number n = nvalue(key); 504 if (numisint(fltvalue(key), &k)) /* index is int? */
488 lua_number2int(k, n);
489 if (luai_numeq(cast_num(k), n)) /* index is int? */
490 return luaH_getint(t, k); /* use specialized version */ 505 return luaH_getint(t, k); /* use specialized version */
491 /* else go through */ 506 /* else go through */
492 } 507 }
@@ -522,7 +537,7 @@ void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
522 cell = cast(TValue *, p); 537 cell = cast(TValue *, p);
523 else { 538 else {
524 TValue k; 539 TValue k;
525 setnvalue(&k, cast_num(key)); 540 setivalue(&k, key);
526 cell = luaH_newkey(L, t, &k); 541 cell = luaH_newkey(L, t, &k);
527 } 542 }
528 setobj2t(L, cell, value); 543 setobj2t(L, cell, value);