diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-22 11:12:07 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1999-11-22 11:12:07 -0200 |
commit | 29ede6aa13144ff7b69c57a87be1ee93f57ae896 (patch) | |
tree | adcfb5dcff7db55481cd675349e23dec0e63c939 /ltable.c | |
parent | 951897c09319ae5474a4b86bb7d615136577caa0 (diff) | |
download | lua-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.c | 80 |
1 files changed, 41 insertions, 39 deletions
@@ -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 | */ |
41 | Node *luaH_mainposition (const Hash *t, const TObject *key) { | 43 | Node *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 | ||
70 | const TObject *luaH_get (const Hash *t, const TObject *key) { | 72 | const 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 | ||
81 | int luaH_pos (const Hash *t, const TObject *key) { | 83 | int 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 | ||
89 | static Node *hashnodecreate (int nhash) { | 91 | static 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 | ||
100 | static void setnodevector (Hash *t, int size) { | 102 | static 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 | ||
108 | Hash *luaH_new (int size) { | 110 | Hash *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 | ||
119 | void luaH_free (Hash *t) { | 121 | void 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 | ||
126 | static int newsize (const Hash *t) { | 128 | static 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 | */ |
144 | static void rehash (Hash *t) { | 146 | static 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 | */ |
200 | void luaH_set (Hash *t, const TObject *key, const TObject *val) { | 202 | void 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 | ||
242 | void luaH_setint (Hash *t, int key, const TObject *val) { | 244 | void 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 | ||
250 | const TObject *luaH_getint (const Hash *t, int key) { | 252 | const 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 | ||