summaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-22 11:12:07 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-22 11:12:07 -0200
commit29ede6aa13144ff7b69c57a87be1ee93f57ae896 (patch)
treeadcfb5dcff7db55481cd675349e23dec0e63c939 /ltable.c
parent951897c09319ae5474a4b86bb7d615136577caa0 (diff)
downloadlua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.gz
lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.bz2
lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.zip
first implementation of multiple states (reentrant code).
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c80
1 files changed, 41 insertions, 39 deletions
diff --git a/ltable.c b/ltable.c
index eceff082..8a207b80 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.28 1999/10/26 10:53:40 roberto Exp roberto $ 2** $Id: ltable.c,v 1.29 1999/11/10 15:39:35 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*/
@@ -18,6 +18,8 @@
18*/ 18*/
19 19
20 20
21#define LUA_REENTRANT
22
21#include "lauxlib.h" 23#include "lauxlib.h"
22#include "lmem.h" 24#include "lmem.h"
23#include "lobject.h" 25#include "lobject.h"
@@ -26,7 +28,7 @@
26#include "lua.h" 28#include "lua.h"
27 29
28 30
29#define gcsize(n) numblocks(n*2, sizeof(Hash)) 31#define gcsize(L, n) numblocks(L, n*2, sizeof(Hash))
30 32
31 33
32 34
@@ -38,7 +40,7 @@
38** returns the `main' position of an element in a table (that is, the index 40** returns the `main' position of an element in a table (that is, the index
39** of its hash value) 41** of its hash value)
40*/ 42*/
41Node *luaH_mainposition (const Hash *t, const TObject *key) { 43Node *luaH_mainposition (lua_State *L, const Hash *t, const TObject *key) {
42 unsigned long h; 44 unsigned long h;
43 switch (ttype(key)) { 45 switch (ttype(key)) {
44 case LUA_T_NUMBER: 46 case LUA_T_NUMBER:
@@ -48,27 +50,27 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
48 h = tsvalue(key)->hash; 50 h = tsvalue(key)->hash;
49 break; 51 break;
50 case LUA_T_ARRAY: 52 case LUA_T_ARRAY:
51 h = IntPoint(avalue(key)); 53 h = IntPoint(L, avalue(key));
52 break; 54 break;
53 case LUA_T_PROTO: 55 case LUA_T_PROTO:
54 h = IntPoint(tfvalue(key)); 56 h = IntPoint(L, tfvalue(key));
55 break; 57 break;
56 case LUA_T_CPROTO: 58 case LUA_T_CPROTO:
57 h = IntPoint(fvalue(key)); 59 h = IntPoint(L, fvalue(key));
58 break; 60 break;
59 case LUA_T_CLOSURE: 61 case LUA_T_CLOSURE:
60 h = IntPoint(clvalue(key)); 62 h = IntPoint(L, clvalue(key));
61 break; 63 break;
62 default: 64 default:
63 lua_error("unexpected type to index table"); 65 lua_error(L, "unexpected type to index table");
64 h = 0; /* to avoid warnings */ 66 h = 0; /* to avoid warnings */
65 } 67 }
66 return &t->node[h%(unsigned int)t->size]; 68 return &t->node[h%(unsigned int)t->size];
67} 69}
68 70
69 71
70const TObject *luaH_get (const Hash *t, const TObject *key) { 72const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) {
71 Node *n = luaH_mainposition(t, key); 73 Node *n = luaH_mainposition(L, t, key);
72 do { 74 do {
73 if (luaO_equalObj(key, &n->key)) 75 if (luaO_equalObj(key, &n->key))
74 return &n->val; 76 return &n->val;
@@ -78,16 +80,16 @@ const TObject *luaH_get (const Hash *t, const TObject *key) {
78} 80}
79 81
80 82
81int luaH_pos (const Hash *t, const TObject *key) { 83int luaH_pos (lua_State *L, const Hash *t, const TObject *key) {
82 const TObject *v = luaH_get(t, key); 84 const TObject *v = luaH_get(L, t, key);
83 return (v == &luaO_nilobject) ? -1 : /* key not found */ 85 return (v == &luaO_nilobject) ? -1 : /* key not found */
84 ((const char *)v - (const char *)(&t->node[0].val))/sizeof(Node); 86 ((const char *)v - (const char *)(&t->node[0].val))/sizeof(Node);
85} 87}
86 88
87 89
88 90
89static Node *hashnodecreate (int nhash) { 91static Node *hashnodecreate (lua_State *L, int nhash) {
90 Node *v = luaM_newvector(nhash, Node); 92 Node *v = luaM_newvector(L, nhash, Node);
91 int i; 93 int i;
92 for (i=0; i<nhash; i++) { 94 for (i=0; i<nhash; i++) {
93 ttype(&v[i].key) = ttype(&v[i].val) = LUA_T_NIL; 95 ttype(&v[i].key) = ttype(&v[i].val) = LUA_T_NIL;
@@ -97,17 +99,17 @@ static Node *hashnodecreate (int nhash) {
97} 99}
98 100
99 101
100static void setnodevector (Hash *t, int size) { 102static void setnodevector (lua_State *L, Hash *t, int size) {
101 t->node = hashnodecreate(size); 103 t->node = hashnodecreate(L, size);
102 t->size = size; 104 t->size = size;
103 t->firstfree = &t->node[size-1]; /* first free position to be used */ 105 t->firstfree = &t->node[size-1]; /* first free position to be used */
104 L->nblocks += gcsize(size); 106 L->nblocks += gcsize(L, size);
105} 107}
106 108
107 109
108Hash *luaH_new (int size) { 110Hash *luaH_new (lua_State *L, int size) {
109 Hash *t = luaM_new(Hash); 111 Hash *t = luaM_new(L, Hash);
110 setnodevector(t, luaO_redimension(size+1)); 112 setnodevector(L, t, luaO_redimension(L, size+1));
111 t->htag = TagDefault; 113 t->htag = TagDefault;
112 t->next = L->roottable; 114 t->next = L->roottable;
113 L->roottable = t; 115 L->roottable = t;
@@ -116,14 +118,14 @@ Hash *luaH_new (int size) {
116} 118}
117 119
118 120
119void luaH_free (Hash *t) { 121void luaH_free (lua_State *L, Hash *t) {
120 L->nblocks -= gcsize(t->size); 122 L->nblocks -= gcsize(L, t->size);
121 luaM_free(t->node); 123 luaM_free(L, t->node);
122 luaM_free(t); 124 luaM_free(L, t);
123} 125}
124 126
125 127
126static int newsize (const Hash *t) { 128static int newsize (lua_State *L, const Hash *t) {
127 Node *v = t->node; 129 Node *v = t->node;
128 int size = t->size; 130 int size = t->size;
129 int realuse = 0; 131 int realuse = 0;
@@ -132,7 +134,7 @@ static int newsize (const Hash *t) {
132 if (ttype(&v[i].val) != LUA_T_NIL) 134 if (ttype(&v[i].val) != LUA_T_NIL)
133 realuse++; 135 realuse++;
134 } 136 }
135 return luaO_redimension(realuse*2); 137 return luaO_redimension(L, realuse*2);
136} 138}
137 139
138 140
@@ -141,19 +143,19 @@ static int newsize (const Hash *t) {
141** main position is free, to avoid needless collisions. In the second stage, 143** main position is free, to avoid needless collisions. In the second stage,
142** we insert the other elements. 144** we insert the other elements.
143*/ 145*/
144static void rehash (Hash *t) { 146static void rehash (lua_State *L, Hash *t) {
145 int oldsize = t->size; 147 int oldsize = t->size;
146 Node *nold = t->node; 148 Node *nold = t->node;
147 int i; 149 int i;
148 L->nblocks -= gcsize(oldsize); 150 L->nblocks -= gcsize(L, oldsize);
149 setnodevector(t, newsize(t)); /* create new array of nodes */ 151 setnodevector(L, t, newsize(L, t)); /* create new array of nodes */
150 /* first loop; set only elements that can go in their main positions */ 152 /* first loop; set only elements that can go in their main positions */
151 for (i=0; i<oldsize; i++) { 153 for (i=0; i<oldsize; i++) {
152 Node *old = nold+i; 154 Node *old = nold+i;
153 if (ttype(&old->val) == LUA_T_NIL) 155 if (ttype(&old->val) == LUA_T_NIL)
154 old->next = NULL; /* `remove' it for next loop */ 156 old->next = NULL; /* `remove' it for next loop */
155 else { 157 else {
156 Node *mp = luaH_mainposition(t, &old->key); /* new main position */ 158 Node *mp = luaH_mainposition(L, t, &old->key); /* new main position */
157 if (ttype(&mp->key) == LUA_T_NIL) { /* is it empty? */ 159 if (ttype(&mp->key) == LUA_T_NIL) { /* is it empty? */
158 mp->key = old->key; /* put element there */ 160 mp->key = old->key; /* put element there */
159 mp->val = old->val; 161 mp->val = old->val;
@@ -180,7 +182,7 @@ static void rehash (Hash *t) {
180 } while (ttype(&t->firstfree->key) != LUA_T_NIL); 182 } while (ttype(&t->firstfree->key) != LUA_T_NIL);
181 } 183 }
182 } 184 }
183 luaM_free(nold); /* free old array */ 185 luaM_free(L, nold); /* free old array */
184} 186}
185 187
186 188
@@ -197,8 +199,8 @@ static void rehash (Hash *t) {
197** pair; therefore, even when `val' points to an element of this table 199** pair; therefore, even when `val' points to an element of this table
198** (this happens when we use `luaH_move'), there is no problem. 200** (this happens when we use `luaH_move'), there is no problem.
199*/ 201*/
200void luaH_set (Hash *t, const TObject *key, const TObject *val) { 202void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val) {
201 Node *mp = luaH_mainposition(t, key); 203 Node *mp = luaH_mainposition(L, t, key);
202 Node *n = mp; 204 Node *n = mp;
203 do { /* check whether `key' is somewhere in the chain */ 205 do { /* check whether `key' is somewhere in the chain */
204 if (luaO_equalObj(key, &n->key)) { 206 if (luaO_equalObj(key, &n->key)) {
@@ -213,7 +215,7 @@ void luaH_set (Hash *t, const TObject *key, const TObject *val) {
213 n = t->firstfree; /* get a free place */ 215 n = t->firstfree; /* get a free place */
214 /* is colliding node out of its main position? (can only happens if 216 /* is colliding node out of its main position? (can only happens if
215 its position if after "firstfree") */ 217 its position if after "firstfree") */
216 if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) { 218 if (mp > n && (othern=luaH_mainposition(L, t, &mp->key)) != mp) {
217 /* yes; move colliding node into free position */ 219 /* yes; move colliding node into free position */
218 while (othern->next != mp) othern = othern->next; /* find previous */ 220 while (othern->next != mp) othern = othern->next; /* find previous */
219 othern->next = n; /* redo the chain with `n' in place of `mp' */ 221 othern->next = n; /* redo the chain with `n' in place of `mp' */
@@ -235,22 +237,22 @@ void luaH_set (Hash *t, const TObject *key, const TObject *val) {
235 else if (t->firstfree == t->node) break; /* cannot decrement from here */ 237 else if (t->firstfree == t->node) break; /* cannot decrement from here */
236 else (t->firstfree)--; 238 else (t->firstfree)--;
237 } 239 }
238 rehash(t); /* no more free places */ 240 rehash(L, t); /* no more free places */
239} 241}
240 242
241 243
242void luaH_setint (Hash *t, int key, const TObject *val) { 244void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val) {
243 TObject index; 245 TObject index;
244 ttype(&index) = LUA_T_NUMBER; 246 ttype(&index) = LUA_T_NUMBER;
245 nvalue(&index) = key; 247 nvalue(&index) = key;
246 luaH_set(t, &index, val); 248 luaH_set(L, t, &index, val);
247} 249}
248 250
249 251
250const TObject *luaH_getint (const Hash *t, int key) { 252const TObject *luaH_getint (lua_State *L, const Hash *t, int key) {
251 TObject index; 253 TObject index;
252 ttype(&index) = LUA_T_NUMBER; 254 ttype(&index) = LUA_T_NUMBER;
253 nvalue(&index) = key; 255 nvalue(&index) = key;
254 return luaH_get(t, &index); 256 return luaH_get(L, t, &index);
255} 257}
256 258