From dabb19fc17acee55f9052c5d17ec07360cec809d Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 10 Jan 2001 16:56:11 -0200 Subject: specialized versions for luaH_set (numbers and strings) --- lapi.c | 6 +-- ldo.c | 4 +- ltable.c | 128 +++++++++++++++++++++++++++++++++++---------------------------- ltable.h | 10 ++--- lvm.c | 31 ++++++---------- 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 @@ /* -** $Id: lapi.c,v 1.114 2000/12/28 12:55:41 roberto Exp roberto $ +** $Id: lapi.c,v 1.115 2001/01/10 17:41:50 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -267,7 +267,7 @@ LUA_API void lua_gettable (lua_State *L, int index) { LUA_API void lua_rawget (lua_State *L, int index) { StkId t = Index(L, index); LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected"); - *(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1); + *(L->top - 1) = *luaH_get(hvalue(t), L->top - 1); } @@ -338,7 +338,7 @@ LUA_API void lua_rawset (lua_State *L, int index) { LUA_API void lua_rawseti (lua_State *L, int index, int n) { StkId o = Index(L, index); LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected"); - *luaH_setint(L, hvalue(o), n) = *(L->top-1); + *luaH_setnum(L, hvalue(o), n) = *(L->top-1); L->top--; } diff --git a/ldo.c b/ldo.c index eb6fd46e..46c397ea 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.111 2000/12/28 12:55:41 roberto Exp roberto $ +** $Id: ldo.c,v 1.112 2001/01/10 16:58:11 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -332,7 +332,7 @@ struct lua_longjmp { static void message (lua_State *L, const char *s) { - const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE); + const TObject *em = luaH_getstr(L->gt, luaS_newliteral(L, LUA_ERRORMESSAGE)); if (ttype(em) == LUA_TFUNCTION) { *L->top = *em; incr_top; diff --git a/ltable.c b/ltable.c index 1895029c..ba1ccbe8 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.61 2000/12/22 16:57:46 roberto Exp roberto $ +** $Id: ltable.c,v 1.62 2000/12/28 12:55:41 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -23,7 +23,6 @@ #include "lmem.h" #include "lobject.h" #include "lstate.h" -#include "lstring.h" #include "ltable.h" @@ -31,6 +30,9 @@ #define TagDefault LUA_TTABLE +#define hashnum(t,n) (&t->node[(luint32)(lint32)(n)&(t->size-1)]) +#define hashstr(t,str) (&t->node[(str)->u.s.hash&(t->size-1)]) + /* ** 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) { luint32 h; switch (ttype(key)) { case LUA_TNUMBER: - h = (luint32)(lint32)nvalue(key); - break; + return hashnum(t, nvalue(key)); case LUA_TSTRING: - h = tsvalue(key)->u.s.hash; - break; + return hashstr(t, tsvalue(key)); case LUA_TUSERDATA: h = IntPoint(tsvalue(key)); break; @@ -57,31 +57,26 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) { default: return NULL; /* invalid key */ } - LUA_ASSERT(h%(unsigned int)t->size == (h&((unsigned int)t->size-1)), - "a&(x-1) == a%x, for x power of 2"); return &t->node[h&(t->size-1)]; } -static const TObject *luaH_getany (lua_State *L, const Hash *t, - const TObject *key) { +static const TObject *luaH_getany (const Hash *t, const TObject *key) { Node *n = luaH_mainposition(t, key); - if (!n) - lua_error(L, "table index is nil"); - else do { + while (n) { if (luaO_equalObj(key, &n->key)) return &n->val; n = n->next; - } while (n); + } return &luaO_nilobject; /* key not found */ } /* specialized version for numbers */ const TObject *luaH_getnum (const Hash *t, lua_Number key) { - Node *n = &t->node[(luint32)(lint32)key&(t->size-1)]; + Node *n = hashnum(t, key); do { - if (ttype(&n->key) == LUA_TNUMBER && nvalue(&n->key) == key) + if (nvalue(&n->key) == key && ttype(&n->key) == LUA_TNUMBER) return &n->val; n = n->next; } while (n); @@ -91,9 +86,9 @@ const TObject *luaH_getnum (const Hash *t, lua_Number key) { /* specialized version for strings */ const TObject *luaH_getstr (const Hash *t, TString *key) { - Node *n = &t->node[key->u.s.hash&(t->size-1)]; + Node *n = hashstr(t, key); do { - if (ttype(&n->key) == LUA_TSTRING && tsvalue(&n->key) == key) + if (tsvalue(&n->key) == key && ttype(&n->key) == LUA_TSTRING) return &n->val; n = n->next; } while (n); @@ -101,11 +96,11 @@ const TObject *luaH_getstr (const Hash *t, TString *key) { } -const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) { +const TObject *luaH_get (const Hash *t, const TObject *key) { switch (ttype(key)) { case LUA_TNUMBER: return luaH_getnum(t, nvalue(key)); case LUA_TSTRING: return luaH_getstr(t, tsvalue(key)); - default: return luaH_getany(L, t, key); + default: return luaH_getany(t, key); } } @@ -115,7 +110,7 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) { if (ttype(key) == LUA_TNIL) i = 0; /* first iteration */ else { - const TObject *v = luaH_get(L, t, key); + const TObject *v = luaH_get(t, key); if (v == &luaO_nilobject) lua_error(L, "invalid key for `next'"); i = (int)(((const char *)v - @@ -224,30 +219,17 @@ static void rehash (lua_State *L, Hash *t) { /* -** inserts a key into a hash table; first, check whether key is -** already present; if not, check whether key's main position is free; -** if not, check whether colliding node is in its main position or not; -** if it is not, move colliding node to an empty place and put new key -** in its main position; otherwise (colliding node is in its main position), -** new key goes to an empty position. +** inserts a new key into a hash table; first, check whether key's main +** position is free; if not, check whether colliding node is in its main +** position or not; if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. */ -TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { - Node *mp = luaH_mainposition(t, key); - Node *n = mp; - if (!mp) - lua_error(L, "table index is nil"); - do { /* check whether `key' is somewhere in the chain */ - if (luaO_equalObj(key, &n->key)) - return &n->val; /* that's all */ - else n = n->next; - } while (n); - /* `key' not found; must insert it */ +static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) { if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */ - Node *othern; /* main position of colliding node */ - n = t->firstfree; /* get a free place */ - /* is colliding node out of its main position? (can only happens if - its position is after "firstfree") */ - if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) { + Node *othern = luaH_mainposition(t, &mp->key); /* `mp' of colliding node */ + Node *n = t->firstfree; /* get a free place */ + if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ while (othern->next != mp) othern = othern->next; /* find previous */ 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) { } -TObject *luaH_setint (lua_State *L, Hash *t, int key) { - TObject index; - ttype(&index) = LUA_TNUMBER; - nvalue(&index) = key; - return luaH_set(L, t, &index); +static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) { + Node *mp = luaH_mainposition(t, key); + Node *n = mp; + if (!mp) + lua_error(L, "table index is nil"); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_equalObj(key, &n->key)) + return &n->val; /* that's all */ + else n = n->next; + } while (n); + return newkey(L, t, mp, key); /* `key' not found; must insert it */ +} + + +TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key) { + TObject kobj; + Node *mp = hashnum(t, key); + Node *n = mp; + do { /* check whether `key' is somewhere in the chain */ + if (nvalue(&n->key) == key && ttype(&n->key) == LUA_TNUMBER) + return &n->val; /* that's all */ + else n = n->next; + } while (n); + /* `key' not found; must insert it */ + ttype(&kobj) = LUA_TNUMBER; + nvalue(&kobj) = key; + return newkey(L, t, mp, &kobj); } -void luaH_setstrnum (lua_State *L, Hash *t, TString *key, lua_Number val) { - TObject *value, index; - ttype(&index) = LUA_TSTRING; - tsvalue(&index) = key; - value = luaH_set(L, t, &index); - ttype(value) = LUA_TNUMBER; - nvalue(value) = val; +TObject *luaH_setstr (lua_State *L, Hash *t, TString *key) { + TObject kobj; + Node *mp = hashstr(t, key); + Node *n = mp; + do { /* check whether `key' is somewhere in the chain */ + if (tsvalue(&n->key) == key && ttype(&n->key) == LUA_TSTRING) + return &n->val; /* that's all */ + else n = n->next; + } while (n); + /* `key' not found; must insert it */ + ttype(&kobj) = LUA_TSTRING; + tsvalue(&kobj) = key; + return newkey(L, t, mp, &kobj); } -const TObject *luaH_getglobal (lua_State *L, const char *name) { - return luaH_getstr(L->gt, luaS_new(L, name)); +TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) { + switch (ttype(key)) { + case LUA_TNUMBER: return luaH_setnum(L, t, nvalue(key)); + case LUA_TSTRING: return luaH_setstr(L, t, tsvalue(key)); + default: return luaH_setany(L, t, key); + } } diff --git a/ltable.h b/ltable.h index 4027f0da..6283a2d5 100644 --- a/ltable.h +++ b/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 1.25 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: ltable.h,v 1.26 2000/12/04 18:33:40 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -16,16 +16,14 @@ Hash *luaH_new (lua_State *L, int nhash); void luaH_free (lua_State *L, Hash *t); -const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key); +const TObject *luaH_get (const Hash *t, const TObject *key); const TObject *luaH_getnum (const Hash *t, lua_Number key); const TObject *luaH_getstr (const Hash *t, TString *key); void luaH_remove (Hash *t, TObject *key); TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); -TObject *luaH_setint (lua_State *L, Hash *t, int key); -void luaH_setstrnum (lua_State *L, Hash *t, TString *key, lua_Number val); -luint32 luaH_hash (lua_State *L, const TObject *key); -const TObject *luaH_getglobal (lua_State *L, const char *name); +TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key); +TObject *luaH_setstr (lua_State *L, Hash *t, TString *key); /* exported only for debugging */ Node *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 @@ /* -** $Id: lvm.c,v 1.149 2000/12/28 12:55:41 roberto Exp roberto $ +** $Id: lvm.c,v 1.150 2001/01/10 17:41:50 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -122,7 +122,7 @@ const TObject *luaV_gettable (lua_State *L, StkId t) { ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */ /* do a primitive get */ - const TObject *h = luaH_get(L, hvalue(t), L->top-1); + const TObject *h = luaH_get(hvalue(t), L->top-1); /* result is no nil or there is no `index' tag method? */ if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL)) return h; /* return result */ @@ -195,21 +195,11 @@ const TObject *luaV_getglobal (lua_State *L, TString *s) { void luaV_setglobal (lua_State *L, TString *s) { - const TObject *oldvalue = luaH_getstr(L->gt, s); + TObject *oldvalue = luaH_setstr(L, L->gt, s); Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL); - if (tm == NULL) { /* is there a tag method? */ - if (oldvalue != &luaO_nilobject) { - /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ - *(TObject *)oldvalue = *(L->top - 1); - } - else { - TObject key; - ttype(&key) = LUA_TSTRING; - tsvalue(&key) = s; - *luaH_set(L, L->gt, &key) = *(L->top - 1); - } - } - else { + if (tm == NULL) /* no tag methods? */ + *oldvalue = *(L->top - 1); /* raw set */ + else { /* call tag method */ luaD_checkstack(L, 3); *(L->top+2) = *(L->top-1); /* new value */ *(L->top+1) = *oldvalue; @@ -320,12 +310,15 @@ void luaV_strconc (lua_State *L, int total, StkId top) { static void luaV_pack (lua_State *L, StkId firstelem) { + TObject *nf; int i; Hash *htab = luaH_new(L, 0); for (i=0; firstelem+itop; i++) - *luaH_setint(L, htab, i+1) = *(firstelem+i); + *luaH_setnum(L, htab, i+1) = *(firstelem+i); /* store counter in field `n' */ - luaH_setstrnum(L, htab, luaS_newliteral(L, "n"), i); + nf = luaH_setstr(L, htab, luaS_newliteral(L, "n")); + ttype(nf) = LUA_TNUMBER; + nvalue(nf) = i; L->top = firstelem; /* remove elements from the stack */ ttype(L->top) = LUA_TTABLE; hvalue(L->top) = htab; @@ -498,7 +491,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { Hash *arr = hvalue(top-n-1); L->top = top-n; /* final value of `top' (in case of errors) */ for (; n; n--) - *luaH_setint(L, arr, n+aux) = *(--top); + *luaH_setnum(L, arr, n+aux) = *(--top); break; } case OP_SETMAP: { -- cgit v1.2.3-55-g6feb