aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-10 16:56:11 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-01-10 16:56:11 -0200
commitdabb19fc17acee55f9052c5d17ec07360cec809d (patch)
tree76983221f936eee7e681559093b3b23f8968e711
parent08496eea8b277d37c4de9cf75a011715ad6a4100 (diff)
downloadlua-dabb19fc17acee55f9052c5d17ec07360cec809d.tar.gz
lua-dabb19fc17acee55f9052c5d17ec07360cec809d.tar.bz2
lua-dabb19fc17acee55f9052c5d17ec07360cec809d.zip
specialized versions for luaH_set (numbers and strings)
-rw-r--r--lapi.c6
-rw-r--r--ldo.c4
-rw-r--r--ltable.c128
-rw-r--r--ltable.h10
-rw-r--r--lvm.c31
5 files changed, 92 insertions, 87 deletions
diff --git a/lapi.c b/lapi.c
index 3f0a75bb..61302603 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.114 2000/12/28 12:55:41 roberto Exp roberto $ 2** $Id: lapi.c,v 1.115 2001/01/10 17:41:50 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -267,7 +267,7 @@ LUA_API void lua_gettable (lua_State *L, int index) {
267LUA_API void lua_rawget (lua_State *L, int index) { 267LUA_API void lua_rawget (lua_State *L, int index) {
268 StkId t = Index(L, index); 268 StkId t = Index(L, index);
269 LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); 269 LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
270 *(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1); 270 *(L->top - 1) = *luaH_get(hvalue(t), L->top - 1);
271} 271}
272 272
273 273
@@ -338,7 +338,7 @@ LUA_API void lua_rawset (lua_State *L, int index) {
338LUA_API void lua_rawseti (lua_State *L, int index, int n) { 338LUA_API void lua_rawseti (lua_State *L, int index, int n) {
339 StkId o = Index(L, index); 339 StkId o = Index(L, index);
340 LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected"); 340 LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
341 *luaH_setint(L, hvalue(o), n) = *(L->top-1); 341 *luaH_setnum(L, hvalue(o), n) = *(L->top-1);
342 L->top--; 342 L->top--;
343} 343}
344 344
diff --git a/ldo.c b/ldo.c
index eb6fd46e..46c397ea 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.111 2000/12/28 12:55:41 roberto Exp roberto $ 2** $Id: ldo.c,v 1.112 2001/01/10 16:58:11 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -332,7 +332,7 @@ struct lua_longjmp {
332 332
333 333
334static void message (lua_State *L, const char *s) { 334static void message (lua_State *L, const char *s) {
335 const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE); 335 const TObject *em = luaH_getstr(L->gt, luaS_newliteral(L, LUA_ERRORMESSAGE));
336 if (ttype(em) == LUA_TFUNCTION) { 336 if (ttype(em) == LUA_TFUNCTION) {
337 *L->top = *em; 337 *L->top = *em;
338 incr_top; 338 incr_top;
diff --git a/ltable.c b/ltable.c
index 1895029c..ba1ccbe8 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.61 2000/12/22 16:57:46 roberto Exp roberto $ 2** $Id: ltable.c,v 1.62 2000/12/28 12:55:41 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*/
@@ -23,7 +23,6 @@
23#include "lmem.h" 23#include "lmem.h"
24#include "lobject.h" 24#include "lobject.h"
25#include "lstate.h" 25#include "lstate.h"
26#include "lstring.h"
27#include "ltable.h" 26#include "ltable.h"
28 27
29 28
@@ -31,6 +30,9 @@
31#define TagDefault LUA_TTABLE 30#define TagDefault LUA_TTABLE
32 31
33 32
33#define hashnum(t,n) (&t->node[(luint32)(lint32)(n)&(t->size-1)])
34#define hashstr(t,str) (&t->node[(str)->u.s.hash&(t->size-1)])
35
34 36
35/* 37/*
36** returns the `main' position of an element in a table (that is, the index 38** returns the `main' position of an element in a table (that is, the index
@@ -40,11 +42,9 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
40 luint32 h; 42 luint32 h;
41 switch (ttype(key)) { 43 switch (ttype(key)) {
42 case LUA_TNUMBER: 44 case LUA_TNUMBER:
43 h = (luint32)(lint32)nvalue(key); 45 return hashnum(t, nvalue(key));
44 break;
45 case LUA_TSTRING: 46 case LUA_TSTRING:
46 h = tsvalue(key)->u.s.hash; 47 return hashstr(t, tsvalue(key));
47 break;
48 case LUA_TUSERDATA: 48 case LUA_TUSERDATA:
49 h = IntPoint(tsvalue(key)); 49 h = IntPoint(tsvalue(key));
50 break; 50 break;
@@ -57,31 +57,26 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
57 default: 57 default:
58 return NULL; /* invalid key */ 58 return NULL; /* invalid key */
59 } 59 }
60 LUA_ASSERT(h%(unsigned int)t->size == (h&((unsigned int)t->size-1)),
61 "a&(x-1) == a%x, for x power of 2");
62 return &t->node[h&(t->size-1)]; 60 return &t->node[h&(t->size-1)];
63} 61}
64 62
65 63
66static const TObject *luaH_getany (lua_State *L, const Hash *t, 64static const TObject *luaH_getany (const Hash *t, const TObject *key) {
67 const TObject *key) {
68 Node *n = luaH_mainposition(t, key); 65 Node *n = luaH_mainposition(t, key);
69 if (!n) 66 while (n) {
70 lua_error(L, "table index is nil");
71 else do {
72 if (luaO_equalObj(key, &n->key)) 67 if (luaO_equalObj(key, &n->key))
73 return &n->val; 68 return &n->val;
74 n = n->next; 69 n = n->next;
75 } while (n); 70 }
76 return &luaO_nilobject; /* key not found */ 71 return &luaO_nilobject; /* key not found */
77} 72}
78 73
79 74
80/* specialized version for numbers */ 75/* specialized version for numbers */
81const TObject *luaH_getnum (const Hash *t, lua_Number key) { 76const TObject *luaH_getnum (const Hash *t, lua_Number key) {
82 Node *n = &t->node[(luint32)(lint32)key&(t->size-1)]; 77 Node *n = hashnum(t, key);
83 do { 78 do {
84 if (ttype(&n->key) == LUA_TNUMBER && nvalue(&n->key) == key) 79 if (nvalue(&n->key) == key && ttype(&n->key) == LUA_TNUMBER)
85 return &n->val; 80 return &n->val;
86 n = n->next; 81 n = n->next;
87 } while (n); 82 } while (n);
@@ -91,9 +86,9 @@ const TObject *luaH_getnum (const Hash *t, lua_Number key) {
91 86
92/* specialized version for strings */ 87/* specialized version for strings */
93const TObject *luaH_getstr (const Hash *t, TString *key) { 88const TObject *luaH_getstr (const Hash *t, TString *key) {
94 Node *n = &t->node[key->u.s.hash&(t->size-1)]; 89 Node *n = hashstr(t, key);
95 do { 90 do {
96 if (ttype(&n->key) == LUA_TSTRING && tsvalue(&n->key) == key) 91 if (tsvalue(&n->key) == key && ttype(&n->key) == LUA_TSTRING)
97 return &n->val; 92 return &n->val;
98 n = n->next; 93 n = n->next;
99 } while (n); 94 } while (n);
@@ -101,11 +96,11 @@ const TObject *luaH_getstr (const Hash *t, TString *key) {
101} 96}
102 97
103 98
104const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) { 99const TObject *luaH_get (const Hash *t, const TObject *key) {
105 switch (ttype(key)) { 100 switch (ttype(key)) {
106 case LUA_TNUMBER: return luaH_getnum(t, nvalue(key)); 101 case LUA_TNUMBER: return luaH_getnum(t, nvalue(key));
107 case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); 102 case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
108 default: return luaH_getany(L, t, key); 103 default: return luaH_getany(t, key);
109 } 104 }
110} 105}
111 106
@@ -115,7 +110,7 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
115 if (ttype(key) == LUA_TNIL) 110 if (ttype(key) == LUA_TNIL)
116 i = 0; /* first iteration */ 111 i = 0; /* first iteration */
117 else { 112 else {
118 const TObject *v = luaH_get(L, t, key); 113 const TObject *v = luaH_get(t, key);
119 if (v == &luaO_nilobject) 114 if (v == &luaO_nilobject)
120 lua_error(L, "invalid key for `next'"); 115 lua_error(L, "invalid key for `next'");
121 i = (int)(((const char *)v - 116 i = (int)(((const char *)v -
@@ -224,30 +219,17 @@ static void rehash (lua_State *L, Hash *t) {
224 219
225 220
226/* 221/*
227** inserts a key into a hash table; first, check whether key is 222** inserts a new key into a hash table; first, check whether key's main
228** already present; if not, check whether key's main position is free; 223** position is free; if not, check whether colliding node is in its main
229** if not, check whether colliding node is in its main position or not; 224** position or not; if it is not, move colliding node to an empty place and
230** if it is not, move colliding node to an empty place and put new key 225** put new key in its main position; otherwise (colliding node is in its main
231** in its main position; otherwise (colliding node is in its main position), 226** position), new key goes to an empty position.
232** new key goes to an empty position.
233*/ 227*/
234TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { 228static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) {
235 Node *mp = luaH_mainposition(t, key);
236 Node *n = mp;
237 if (!mp)
238 lua_error(L, "table index is nil");
239 do { /* check whether `key' is somewhere in the chain */
240 if (luaO_equalObj(key, &n->key))
241 return &n->val; /* that's all */
242 else n = n->next;
243 } while (n);
244 /* `key' not found; must insert it */
245 if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */ 229 if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */
246 Node *othern; /* main position of colliding node */ 230 Node *othern = luaH_mainposition(t, &mp->key); /* `mp' of colliding node */
247 n = t->firstfree; /* get a free place */ 231 Node *n = t->firstfree; /* get a free place */
248 /* is colliding node out of its main position? (can only happens if 232 if (othern != mp) { /* is colliding node out of its main position? */
249 its position is after "firstfree") */
250 if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) {
251 /* yes; move colliding node into free position */ 233 /* yes; move colliding node into free position */
252 while (othern->next != mp) othern = othern->next; /* find previous */ 234 while (othern->next != mp) othern = othern->next; /* find previous */
253 othern->next = n; /* redo the chain with `n' in place of `mp' */ 235 othern->next = n; /* redo the chain with `n' in place of `mp' */
@@ -273,25 +255,57 @@ TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
273} 255}
274 256
275 257
276TObject *luaH_setint (lua_State *L, Hash *t, int key) { 258static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) {
277 TObject index; 259 Node *mp = luaH_mainposition(t, key);
278 ttype(&index) = LUA_TNUMBER; 260 Node *n = mp;
279 nvalue(&index) = key; 261 if (!mp)
280 return luaH_set(L, t, &index); 262 lua_error(L, "table index is nil");
263 do { /* check whether `key' is somewhere in the chain */
264 if (luaO_equalObj(key, &n->key))
265 return &n->val; /* that's all */
266 else n = n->next;
267 } while (n);
268 return newkey(L, t, mp, key); /* `key' not found; must insert it */
269}
270
271
272TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) {
273 TObject kobj;
274 Node *mp = hashnum(t, key);
275 Node *n = mp;
276 do { /* check whether `key' is somewhere in the chain */
277 if (nvalue(&n->key) == key && ttype(&n->key) == LUA_TNUMBER)
278 return &n->val; /* that's all */
279 else n = n->next;
280 } while (n);
281 /* `key' not found; must insert it */
282 ttype(&kobj) = LUA_TNUMBER;
283 nvalue(&kobj) = key;
284 return newkey(L, t, mp, &kobj);
281} 285}
282 286
283 287
284void luaH_setstrnum (lua_State *L, Hash *t, TString *key, lua_Number val) { 288TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) {
285 TObject *value, index; 289 TObject kobj;
286 ttype(&index) = LUA_TSTRING; 290 Node *mp = hashstr(t, key);
287 tsvalue(&index) = key; 291 Node *n = mp;
288 value = luaH_set(L, t, &index); 292 do { /* check whether `key' is somewhere in the chain */
289 ttype(value) = LUA_TNUMBER; 293 if (tsvalue(&n->key) == key && ttype(&n->key) == LUA_TSTRING)
290 nvalue(value) = val; 294 return &n->val; /* that's all */
295 else n = n->next;
296 } while (n);
297 /* `key' not found; must insert it */
298 ttype(&kobj) = LUA_TSTRING;
299 tsvalue(&kobj) = key;
300 return newkey(L, t, mp, &kobj);
291} 301}
292 302
293 303
294const TObject *luaH_getglobal (lua_State *L, const char *name) { 304TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
295 return luaH_getstr(L->gt, luaS_new(L, name)); 305 switch (ttype(key)) {
306 case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key));
307 case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key));
308 default: return luaH_setany(L, t, key);
309 }
296} 310}
297 311
diff --git a/ltable.h b/ltable.h
index 4027f0da..6283a2d5 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 1.25 2000/11/24 17:39:56 roberto Exp roberto $ 2** $Id: ltable.h,v 1.26 2000/12/04 18:33:40 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*/
@@ -16,16 +16,14 @@
16 16
17Hash *luaH_new (lua_State *L, int nhash); 17Hash *luaH_new (lua_State *L, int nhash);
18void luaH_free (lua_State *L, Hash *t); 18void luaH_free (lua_State *L, Hash *t);
19const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key); 19const TObject *luaH_get (const Hash *t, const TObject *key);
20const TObject *luaH_getnum (const Hash *t, lua_Number key); 20const TObject *luaH_getnum (const Hash *t, lua_Number key);
21const TObject *luaH_getstr (const Hash *t, TString *key); 21const TObject *luaH_getstr (const Hash *t, TString *key);
22void luaH_remove (Hash *t, TObject *key); 22void luaH_remove (Hash *t, TObject *key);
23TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); 23TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
24Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); 24Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
25TObject *luaH_setint (lua_State *L, Hash *t, int key); 25TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);
26void luaH_setstrnum (lua_State *L, Hash *t, TString *key, lua_Number val); 26TObject *luaH_setstr (lua_State *L, Hash *t, TString *key);
27luint32 luaH_hash (lua_State *L, const TObject *key);
28const TObject *luaH_getglobal (lua_State *L, const char *name);
29 27
30/* exported only for debugging */ 28/* exported only for debugging */
31Node *luaH_mainposition (const Hash *t, const TObject *key); 29Node *luaH_mainposition (const Hash *t, const TObject *key);
diff --git a/lvm.c b/lvm.c
index 0642db6b..a324ea69 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.149 2000/12/28 12:55:41 roberto Exp roberto $ 2** $Id: lvm.c,v 1.150 2001/01/10 17:41:50 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -122,7 +122,7 @@ const TObject *luaV_gettable (lua_State *L, StkId t) {
122 ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ 122 ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */
123 luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */ 123 luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */
124 /* do a primitive get */ 124 /* do a primitive get */
125 const TObject *h = luaH_get(L, hvalue(t), L->top-1); 125 const TObject *h = luaH_get(hvalue(t), L->top-1);
126 /* result is no nil or there is no `index' tag method? */ 126 /* result is no nil or there is no `index' tag method? */
127 if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL)) 127 if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL))
128 return h; /* return result */ 128 return h; /* return result */
@@ -195,21 +195,11 @@ const TObject *luaV_getglobal (lua_State *L, TString *s) {
195 195
196 196
197void luaV_setglobal (lua_State *L, TString *s) { 197void luaV_setglobal (lua_State *L, TString *s) {
198 const TObject *oldvalue = luaH_getstr(L->gt, s); 198 TObject *oldvalue = luaH_setstr(L, L->gt, s);
199 Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL); 199 Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL);
200 if (tm == NULL) { /* is there a tag method? */ 200 if (tm == NULL) /* no tag methods? */
201 if (oldvalue != &luaO_nilobject) { 201 *oldvalue = *(L->top - 1); /* raw set */
202 /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ 202 else { /* call tag method */
203 *(TObject *)oldvalue = *(L->top - 1);
204 }
205 else {
206 TObject key;
207 ttype(&key) = LUA_TSTRING;
208 tsvalue(&key) = s;
209 *luaH_set(L, L->gt, &key) = *(L->top - 1);
210 }
211 }
212 else {
213 luaD_checkstack(L, 3); 203 luaD_checkstack(L, 3);
214 *(L->top+2) = *(L->top-1); /* new value */ 204 *(L->top+2) = *(L->top-1); /* new value */
215 *(L->top+1) = *oldvalue; 205 *(L->top+1) = *oldvalue;
@@ -320,12 +310,15 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
320 310
321 311
322static void luaV_pack (lua_State *L, StkId firstelem) { 312static void luaV_pack (lua_State *L, StkId firstelem) {
313 TObject *nf;
323 int i; 314 int i;
324 Hash *htab = luaH_new(L, 0); 315 Hash *htab = luaH_new(L, 0);
325 for (i=0; firstelem+i<L->top; i++) 316 for (i=0; firstelem+i<L->top; i++)
326 *luaH_setint(L, htab, i+1) = *(firstelem+i); 317 *luaH_setnum(L, htab, i+1) = *(firstelem+i);
327 /* store counter in field `n' */ 318 /* store counter in field `n' */
328 luaH_setstrnum(L, htab, luaS_newliteral(L, "n"), i); 319 nf = luaH_setstr(L, htab, luaS_newliteral(L, "n"));
320 ttype(nf) = LUA_TNUMBER;
321 nvalue(nf) = i;
329 L->top = firstelem; /* remove elements from the stack */ 322 L->top = firstelem; /* remove elements from the stack */
330 ttype(L->top) = LUA_TTABLE; 323 ttype(L->top) = LUA_TTABLE;
331 hvalue(L->top) = htab; 324 hvalue(L->top) = htab;
@@ -498,7 +491,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
498 Hash *arr = hvalue(top-n-1); 491 Hash *arr = hvalue(top-n-1);
499 L->top = top-n; /* final value of `top' (in case of errors) */ 492 L->top = top-n; /* final value of `top' (in case of errors) */
500 for (; n; n--) 493 for (; n; n--)
501 *luaH_setint(L, arr, n+aux) = *(--top); 494 *luaH_setnum(L, arr, n+aux) = *(--top);
502 break; 495 break;
503 } 496 }
504 case OP_SETMAP: { 497 case OP_SETMAP: {