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 | ||
