Browse Source

Some cleaning in the new table API

pull/33/head
Roberto Ierusalimschy 2 years ago
parent
commit
819bd51d87
  1. 70
      lapi.c
  2. 8
      lcode.c
  3. 10
      llex.c
  4. 102
      ltable.c
  5. 37
      ltable.h
  6. 11
      ltm.c
  7. 112
      lvm.c
  8. 49
      lvm.h

70
lapi.c

@ -637,16 +637,16 @@ LUA_API int lua_pushthread (lua_State *L) {
l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) { l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
int aux; int hres;
TString *str = luaS_new(L, k); TString *str = luaS_new(L, k);
luaV_fastget1(t, str, s2v(L->top.p), luaH_getstr1, aux); luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, hres);
if (aux == HOK) { if (hres == HOK) {
api_incr_top(L); api_incr_top(L);
} }
else { else {
setsvalue2s(L, L->top.p, str); setsvalue2s(L, L->top.p, str);
api_incr_top(L); api_incr_top(L);
luaV_finishget1(L, t, s2v(L->top.p - 1), L->top.p - 1, aux); luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, hres);
} }
lua_unlock(L); lua_unlock(L);
return ttype(s2v(L->top.p - 1)); return ttype(s2v(L->top.p - 1));
@ -672,13 +672,13 @@ LUA_API int lua_getglobal (lua_State *L, const char *name) {
LUA_API int lua_gettable (lua_State *L, int idx) { LUA_API int lua_gettable (lua_State *L, int idx) {
int aux; int hres;
TValue *t; TValue *t;
lua_lock(L); lua_lock(L);
t = index2value(L, idx); t = index2value(L, idx);
luaV_fastget1(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get1, aux); luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, hres);
if (aux != HOK) if (hres != HOK)
luaV_finishget1(L, t, s2v(L->top.p - 1), L->top.p - 1, aux); luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, hres);
lua_unlock(L); lua_unlock(L);
return ttype(s2v(L->top.p - 1)); return ttype(s2v(L->top.p - 1));
} }
@ -692,14 +692,14 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
TValue *t; TValue *t;
int aux; int hres;
lua_lock(L); lua_lock(L);
t = index2value(L, idx); t = index2value(L, idx);
luaV_fastgeti1(t, n, s2v(L->top.p), aux); luaV_fastgeti(t, n, s2v(L->top.p), hres);
if (aux != HOK) { if (hres != HOK) {
TValue key; TValue key;
setivalue(&key, n); setivalue(&key, n);
luaV_finishget1(L, t, &key, L->top.p, aux); luaV_finishget(L, t, &key, L->top.p, hres);
} }
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
@ -707,11 +707,9 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
} }
l_sinline int finishrawget (lua_State *L, const TValue *val) { l_sinline int finishrawget (lua_State *L, int hres) {
if (isempty(val)) /* avoid copying empty items to the stack */ if (hres != HOK) /* avoid copying empty items to the stack */
setnilvalue(s2v(L->top.p)); setnilvalue(s2v(L->top.p));
else
setobj2s(L, L->top.p, val);
api_incr_top(L); api_incr_top(L);
lua_unlock(L); lua_unlock(L);
return ttype(s2v(L->top.p - 1)); return ttype(s2v(L->top.p - 1));
@ -727,13 +725,13 @@ static Table *gettable (lua_State *L, int idx) {
LUA_API int lua_rawget (lua_State *L, int idx) { LUA_API int lua_rawget (lua_State *L, int idx) {
Table *t; Table *t;
const TValue *val; int hres;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
t = gettable(L, idx); t = gettable(L, idx);
val = luaH_get(t, s2v(L->top.p - 1)); hres = luaH_get(t, s2v(L->top.p - 1), s2v(L->top.p - 1));
L->top.p--; /* remove key */ L->top.p--; /* remove key */
return finishrawget(L, val); return finishrawget(L, hres);
} }
@ -741,7 +739,7 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
Table *t; Table *t;
lua_lock(L); lua_lock(L);
t = gettable(L, idx); t = gettable(L, idx);
return finishrawget(L, luaH_getint(t, n)); return finishrawget(L, luaH_getint(t, n, s2v(L->top.p)));
} }
@ -751,7 +749,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
lua_lock(L); lua_lock(L);
t = gettable(L, idx); t = gettable(L, idx);
setpvalue(&k, cast_voidp(p)); setpvalue(&k, cast_voidp(p));
return finishrawget(L, luaH_get(t, &k)); return finishrawget(L, luaH_get(t, &k, s2v(L->top.p)));
} }
@ -823,18 +821,18 @@ LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
** t[k] = value at the top of the stack (where 'k' is a string) ** t[k] = value at the top of the stack (where 'k' is a string)
*/ */
static void auxsetstr (lua_State *L, const TValue *t, const char *k) { static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
int aux; int hres;
TString *str = luaS_new(L, k); TString *str = luaS_new(L, k);
api_checknelems(L, 1); api_checknelems(L, 1);
luaV_fastset1(t, str, s2v(L->top.p - 1), aux, luaH_setstr1); luaV_fastset(t, str, s2v(L->top.p - 1), hres, luaH_psetstr);
if (aux == HOK) { if (hres == HOK) {
luaV_finishfastset1(L, t, s2v(L->top.p - 1)); luaV_finishfastset(L, t, s2v(L->top.p - 1));
L->top.p--; /* pop value */ L->top.p--; /* pop value */
} }
else { else {
setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */ setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */
api_incr_top(L); api_incr_top(L);
luaV_finishset1(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), aux); luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), hres);
L->top.p -= 2; /* pop value and key */ L->top.p -= 2; /* pop value and key */
} }
lua_unlock(L); /* lock done by caller */ lua_unlock(L); /* lock done by caller */
@ -851,16 +849,16 @@ LUA_API void lua_setglobal (lua_State *L, const char *name) {
LUA_API void lua_settable (lua_State *L, int idx) { LUA_API void lua_settable (lua_State *L, int idx) {
TValue *t; TValue *t;
int aux; int hres;
lua_lock(L); lua_lock(L);
api_checknelems(L, 2); api_checknelems(L, 2);
t = index2value(L, idx); t = index2value(L, idx);
luaV_fastset1(t, s2v(L->top.p - 2), s2v(L->top.p - 1), aux, luaH_set1); luaV_fastset(t, s2v(L->top.p - 2), s2v(L->top.p - 1), hres, luaH_pset);
if (aux == HOK) { if (hres == HOK) {
luaV_finishfastset1(L, t, s2v(L->top.p - 1)); luaV_finishfastset(L, t, s2v(L->top.p - 1));
} }
else else
luaV_finishset1(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), aux); luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), hres);
L->top.p -= 2; /* pop index and value */ L->top.p -= 2; /* pop index and value */
lua_unlock(L); lua_unlock(L);
} }
@ -874,18 +872,18 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
TValue *t; TValue *t;
int aux; int hres;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
t = index2value(L, idx); t = index2value(L, idx);
luaV_fastseti1(t, n, s2v(L->top.p - 1), aux); luaV_fastseti(t, n, s2v(L->top.p - 1), hres);
if (aux == HOK) { if (hres == HOK) {
luaV_finishfastset1(L, t, s2v(L->top.p - 1)); luaV_finishfastset(L, t, s2v(L->top.p - 1));
} }
else { else {
TValue temp; TValue temp;
setivalue(&temp, n); setivalue(&temp, n);
luaV_finishset1(L, t, &temp, s2v(L->top.p - 1), aux); luaV_finishset(L, t, &temp, s2v(L->top.p - 1), hres);
} }
L->top.p--; /* pop value */ L->top.p--; /* pop value */
lua_unlock(L); lua_unlock(L);

8
lcode.c

@ -544,10 +544,10 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
TValue val; TValue val;
lua_State *L = fs->ls->L; lua_State *L = fs->ls->L;
Proto *f = fs->f; Proto *f = fs->f;
const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */ int aux = luaH_get(fs->ls->h, key, &val); /* query scanner table */
int k, oldsize; int k, oldsize;
if (ttisinteger(idx)) { /* is there an index there? */ if (aux == HOK && ttisinteger(&val)) { /* is there an index there? */
k = cast_int(ivalue(idx)); k = cast_int(ivalue(&val));
/* correct value? (warning: must distinguish floats from integers!) */ /* correct value? (warning: must distinguish floats from integers!) */
if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) &&
luaV_rawequalobj(&f->k[k], v)) luaV_rawequalobj(&f->k[k], v))
@ -559,7 +559,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
/* numerical value does not need GC barrier; /* numerical value does not need GC barrier;
table has no metatable, so it does not need to invalidate cache */ table has no metatable, so it does not need to invalidate cache */
setivalue(&val, k); setivalue(&val, k);
luaH_finishset(L, fs->ls->h, key, idx, &val); luaH_set(L, fs->ls->h, key, &val);
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
setobj(L, &f->k[k], v); setobj(L, &f->k[k], v);

10
llex.c

@ -134,13 +134,13 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
TString *luaX_newstring (LexState *ls, const char *str, size_t l) { TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
lua_State *L = ls->L; lua_State *L = ls->L;
TString *ts = luaS_newlstr(L, str, l); /* create new string */ TString *ts = luaS_newlstr(L, str, l); /* create new string */
const TValue *o = luaH_getstr(ls->h, ts); TString *oldts = luaH_getstrkey(ls->h, ts);
if (!ttisnil(o)) /* string already present? */ if (oldts != NULL) /* string already present? */
ts = keystrval(nodefromval(o)); /* get saved copy */ return oldts; /* use it */
else { /* not in use yet */ else { /* create a new entry */
TValue *stv = s2v(L->top.p++); /* reserve stack space for string */ TValue *stv = s2v(L->top.p++); /* reserve stack space for string */
setsvalue(L, stv, ts); /* temporarily anchor the string */ setsvalue(L, stv, ts); /* temporarily anchor the string */
luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */ luaH_set(L, ls->h, stv, stv); /* t[string] = string */
/* table is not a metatable, so it does not need to invalidate cache */ /* table is not a metatable, so it does not need to invalidate cache */
luaC_checkGC(L); luaC_checkGC(L);
L->top.p--; /* remove string from stack */ L->top.p--; /* remove string from stack */

102
ltable.c

@ -756,7 +756,7 @@ static const TValue *getintfromhash (Table *t, lua_Integer key) {
** one more than the limit (so that it can be incremented without ** one more than the limit (so that it can be incremented without
** changing the real size of the array). ** changing the real size of the array).
*/ */
const TValue *luaH_getint (Table *t, lua_Integer key) { static const TValue *Hgetint (Table *t, lua_Integer key) {
const TValue *slot = getintfromarray(t, key); const TValue *slot = getintfromarray(t, key);
if (slot != NULL) if (slot != NULL)
return slot; return slot;
@ -775,15 +775,15 @@ static int finishnodeget (const TValue *val, TValue *res) {
} }
int luaH_getint1 (Table *t, lua_Integer key, TValue *res) { int luaH_getint (Table *t, lua_Integer key, TValue *res) {
return finishnodeget(luaH_getint(t, key), res); return finishnodeget(Hgetint(t, key), res);
} }
/* /*
** search function for short strings ** search function for short strings
*/ */
const TValue *luaH_getshortstr (Table *t, TString *key) { const TValue *luaH_Hgetshortstr (Table *t, TString *key) {
Node *n = hashstr(t, key); Node *n = hashstr(t, key);
lua_assert(key->tt == LUA_VSHRSTR); lua_assert(key->tt == LUA_VSHRSTR);
for (;;) { /* check whether 'key' is somewhere in the chain */ for (;;) { /* check whether 'key' is somewhere in the chain */
@ -799,14 +799,14 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
} }
int luaH_getshortstr1 (Table *t, TString *key, TValue *res) { int luaH_getshortstr (Table *t, TString *key, TValue *res) {
return finishnodeget(luaH_getshortstr(t, key), res); return finishnodeget(luaH_Hgetshortstr(t, key), res);
} }
const TValue *luaH_getstr (Table *t, TString *key) { static const TValue *Hgetstr (Table *t, TString *key) {
if (key->tt == LUA_VSHRSTR) if (key->tt == LUA_VSHRSTR)
return luaH_getshortstr(t, key); return luaH_Hgetshortstr(t, key);
else { /* for long strings, use generic case */ else { /* for long strings, use generic case */
TValue ko; TValue ko;
setsvalue(cast(lua_State *, NULL), &ko, key); setsvalue(cast(lua_State *, NULL), &ko, key);
@ -815,23 +815,32 @@ const TValue *luaH_getstr (Table *t, TString *key) {
} }
int luaH_getstr1 (Table *t, TString *key, TValue *res) { int luaH_getstr (Table *t, TString *key, TValue *res) {
return finishnodeget(luaH_getstr(t, key), res); return finishnodeget(Hgetstr(t, key), res);
}
TString *luaH_getstrkey (Table *t, TString *key) {
const TValue *o = Hgetstr(t, key);
if (!isabstkey(o)) /* string already present? */
return keystrval(nodefromval(o)); /* get saved copy */
else
return NULL;
} }
/* /*
** main search function ** main search function
*/ */
const TValue *luaH_get (Table *t, const TValue *key) { static const TValue *Hget (Table *t, const TValue *key) {
switch (ttypetag(key)) { switch (ttypetag(key)) {
case LUA_VSHRSTR: return luaH_getshortstr(t, tsvalue(key)); case LUA_VSHRSTR: return luaH_Hgetshortstr(t, tsvalue(key));
case LUA_VNUMINT: return luaH_getint(t, ivalue(key)); case LUA_VNUMINT: return Hgetint(t, ivalue(key));
case LUA_VNIL: return &absentkey; case LUA_VNIL: return &absentkey;
case LUA_VNUMFLT: { case LUA_VNUMFLT: {
lua_Integer k; lua_Integer k;
if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */
return luaH_getint(t, k); /* use specialized version */ return Hgetint(t, k); /* use specialized version */
/* else... */ /* else... */
} /* FALLTHROUGH */ } /* FALLTHROUGH */
default: default:
@ -840,8 +849,8 @@ const TValue *luaH_get (Table *t, const TValue *key) {
} }
int luaH_get1 (Table *t, const TValue *key, TValue *res) { int luaH_get (Table *t, const TValue *key, TValue *res) {
return finishnodeget(luaH_get(t, key), res); return finishnodeget(Hget(t, key), res);
} }
@ -856,7 +865,7 @@ static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
} }
int luaH_setint1 (Table *t, lua_Integer key, TValue *val) { int luaH_psetint (Table *t, lua_Integer key, TValue *val) {
const TValue *slot = getintfromarray(t, key); const TValue *slot = getintfromarray(t, key);
if (slot != NULL) { if (slot != NULL) {
if (!ttisnil(slot)) { if (!ttisnil(slot)) {
@ -871,25 +880,25 @@ int luaH_setint1 (Table *t, lua_Integer key, TValue *val) {
} }
int luaH_setshortstr1 (Table *t, TString *key, TValue *val) { int luaH_psetshortstr (Table *t, TString *key, TValue *val) {
return finishnodeset(t, luaH_getshortstr(t, key), val); return finishnodeset(t, luaH_Hgetshortstr(t, key), val);
} }
int luaH_setstr1 (Table *t, TString *key, TValue *val) { int luaH_psetstr (Table *t, TString *key, TValue *val) {
return finishnodeset(t, luaH_getstr(t, key), val); return finishnodeset(t, Hgetstr(t, key), val);
} }
int luaH_set1 (Table *t, const TValue *key, TValue *val) { int luaH_pset (Table *t, const TValue *key, TValue *val) {
switch (ttypetag(key)) { switch (ttypetag(key)) {
case LUA_VSHRSTR: return luaH_setshortstr1(t, tsvalue(key), val); case LUA_VSHRSTR: return luaH_psetshortstr(t, tsvalue(key), val);
case LUA_VNUMINT: return luaH_setint1(t, ivalue(key), val); case LUA_VNUMINT: return luaH_psetint(t, ivalue(key), val);
case LUA_VNIL: return HNOTFOUND; case LUA_VNIL: return HNOTFOUND;
case LUA_VNUMFLT: { case LUA_VNUMFLT: {
lua_Integer k; lua_Integer k;
if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */
return luaH_setint1(t, k, val); /* use specialized version */ return luaH_psetint(t, k, val); /* use specialized version */
/* else... */ /* else... */
} /* FALLTHROUGH */ } /* FALLTHROUGH */
default: default:
@ -903,26 +912,20 @@ int luaH_set1 (Table *t, const TValue *key, TValue *val) {
** Beware: when using this function you probably need to check a GC ** Beware: when using this function you probably need to check a GC
** barrier and invalidate the TM cache. ** barrier and invalidate the TM cache.
*/ */
void luaH_finishset (lua_State *L, Table *t, const TValue *key,
const TValue *slot, TValue *value) {
if (isabstkey(slot))
luaH_newkey(L, t, key, value);
else
setobj2t(L, cast(TValue *, slot), value);
}
void luaH_finishset1 (lua_State *L, Table *t, const TValue *key, void luaH_finishset (lua_State *L, Table *t, const TValue *key,
TValue *value, int aux) { TValue *value, int hres) {
if (aux == HNOTFOUND) { lua_assert(hres != HOK);
if (hres == HNOTFOUND) {
luaH_newkey(L, t, key, value); luaH_newkey(L, t, key, value);
} }
else if (aux > 0) { /* regular Node? */ else if (hres > 0) { /* regular Node? */
setobj2t(L, gval(gnode(t, aux - HFIRSTNODE)), value); setobj2t(L, gval(gnode(t, hres - HFIRSTNODE)), value);
} }
else { /* array entry */ else { /* array entry */
aux = ~aux; /* real index */ hres = ~hres; /* real index */
val2arr(t, aux, getArrTag(t, aux), value); val2arr(t, hres, getArrTag(t, hres), value);
} }
} }
@ -932,20 +935,19 @@ void luaH_finishset1 (lua_State *L, Table *t, const TValue *key,
** barrier and invalidate the TM cache. ** barrier and invalidate the TM cache.
*/ */
void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
const TValue *slot = luaH_get(t, key); int hres = luaH_pset(t, key, value);
luaH_finishset(L, t, key, slot, value); if (hres != HOK)
luaH_finishset(L, t, key, value, hres);
} }
void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
const TValue *p = luaH_getint(t, key); int hres = luaH_psetint(t, key, value);
if (isabstkey(p)) { if (hres != HOK) {
TValue k; TValue k;
setivalue(&k, key); setivalue(&k, key);
luaH_newkey(L, t, &k, value); luaH_finishset(L, t, &k, value, hres);
} }
else
setobj2t(L, cast(TValue *, p), value);
} }
@ -971,16 +973,16 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
j *= 2; j *= 2;
else { else {
j = LUA_MAXINTEGER; j = LUA_MAXINTEGER;
if (isempty(luaH_getint(t, j))) /* t[j] not present? */ if (isempty(Hgetint(t, j))) /* t[j] not present? */
break; /* 'j' now is an absent index */ break; /* 'j' now is an absent index */
else /* weird case */ else /* weird case */
return j; /* well, max integer is a boundary... */ return j; /* well, max integer is a boundary... */
} }
} while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */ } while (!isempty(Hgetint(t, j))); /* repeat until an absent t[j] */
/* i < j && t[i] present && t[j] absent */ /* i < j && t[i] present && t[j] absent */
while (j - i > 1u) { /* do a binary search between them */ while (j - i > 1u) { /* do a binary search between them */
lua_Unsigned m = (i + j) / 2; lua_Unsigned m = (i + j) / 2;
if (isempty(luaH_getint(t, m))) j = m; if (isempty(Hgetint(t, m))) j = m;
else i = m; else i = m;
} }
return i; return i;
@ -1071,7 +1073,7 @@ lua_Unsigned luaH_getn (Table *t) {
/* (3) 'limit' is the last element and either is zero or present in table */ /* (3) 'limit' is the last element and either is zero or present in table */
lua_assert(limit == luaH_realasize(t) && lua_assert(limit == luaH_realasize(t) &&
(limit == 0 || !isempty(&t->array[limit - 1]))); (limit == 0 || !isempty(&t->array[limit - 1])));
if (isdummy(t) || isempty(luaH_getint(t, cast(lua_Integer, limit + 1)))) if (isdummy(t) || isempty(Hgetint(t, cast(lua_Integer, limit + 1))))
return limit; /* 'limit + 1' is absent */ return limit; /* 'limit + 1' is absent */
else /* 'limit + 1' is also present */ else /* 'limit + 1' is also present */
return hash_search(t, limit); return hash_search(t, limit);

37
ltable.h

@ -35,12 +35,22 @@
#define nodefromval(v) cast(Node *, (v)) #define nodefromval(v) cast(Node *, (v))
/* results from get/set */ /* results from get/pset */
#define HOK 0 #define HOK 0
#define HNOTFOUND 1 #define HNOTFOUND 1
#define HNOTATABLE 2 #define HNOTATABLE 2
#define HFIRSTNODE 3 #define HFIRSTNODE 3
/*
** Besides these values, pset (pre-set) operations may also return an
** encoding of where the value should go (usually called 'hres'). That
** means that there is a slot with that key but with no value. (pset
** cannot set that value because there might be a metamethod.) If the
** slot is in the hash part, the encoding is (HFIRSTNODE + hash index);
** if the slot is in the array part, the encoding is (~array index).
*/
/* fast access to components of array values */ /* fast access to components of array values */
#define getArrTag(t,k) (&(t)->array[k - 1].tt_) #define getArrTag(t,k) (&(t)->array[k - 1].tt_)
@ -55,29 +65,26 @@
(*tag = (val)->tt_, *getArrVal(h,k) = (val)->value_) (*tag = (val)->tt_, *getArrVal(h,k) = (val)->value_)
LUAI_FUNC int luaH_getshortstr1 (Table *t, TString *key, TValue *res); LUAI_FUNC int luaH_getshortstr (Table *t, TString *key, TValue *res);
LUAI_FUNC int luaH_getstr1 (Table *t, TString *key, TValue *res); LUAI_FUNC int luaH_getstr (Table *t, TString *key, TValue *res);
LUAI_FUNC int luaH_get1 (Table *t, const TValue *key, TValue *res); LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res);
LUAI_FUNC int luaH_getint1 (Table *t, lua_Integer key, TValue *res); LUAI_FUNC int luaH_getint (Table *t, lua_Integer key, TValue *res);
LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key);
LUAI_FUNC int luaH_setint1 (Table *t, lua_Integer key, TValue *val); LUAI_FUNC int luaH_psetint (Table *t, lua_Integer key, TValue *val);
LUAI_FUNC int luaH_setshortstr1 (Table *t, TString *key, TValue *val); LUAI_FUNC int luaH_psetshortstr (Table *t, TString *key, TValue *val);
LUAI_FUNC int luaH_setstr1 (Table *t, TString *key, TValue *val); LUAI_FUNC int luaH_psetstr (Table *t, TString *key, TValue *val);
LUAI_FUNC int luaH_set1 (Table *t, const TValue *key, TValue *val); LUAI_FUNC int luaH_pset (Table *t, const TValue *key, TValue *val);
LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
TValue *value); TValue *value);
LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
TValue *value); TValue *value);
LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
TValue *value); TValue *value);
LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
const TValue *slot, TValue *value);
LUAI_FUNC void luaH_finishset1 (lua_State *L, Table *t, const TValue *key,
TValue *value, int aux); TValue *value, int aux);
LUAI_FUNC Table *luaH_new (lua_State *L); LUAI_FUNC Table *luaH_new (lua_State *L);
LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,

11
ltm.c

@ -58,7 +58,7 @@ void luaT_init (lua_State *L) {
** tag methods ** tag methods
*/ */
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm = luaH_getshortstr(events, ename); const TValue *tm = luaH_Hgetshortstr(events, ename);
lua_assert(event <= TM_EQ); lua_assert(event <= TM_EQ);
if (notm(tm)) { /* no tag method? */ if (notm(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */ events->flags |= cast_byte(1u<<event); /* cache this fact */
@ -80,7 +80,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
default: default:
mt = G(L)->mt[ttype(o)]; mt = G(L)->mt[ttype(o)];
} }
return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); return (mt ? luaH_Hgetshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue);
} }
@ -92,9 +92,10 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
Table *mt; Table *mt;
if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); TValue name;
if (ttisstring(name)) /* is '__name' a string? */ int hres = luaH_getshortstr(mt, luaS_new(L, "__name"), &name);
return getstr(tsvalue(name)); /* use it as type name */ if (hres == HOK && ttisstring(&name)) /* is '__name' a string? */
return getstr(tsvalue(&name)); /* use it as type name */
} }
return ttypename(ttype(o)); /* else use standard type name */ return ttypename(ttype(o)); /* else use standard type name */
} }

112
lvm.c

@ -281,15 +281,13 @@ static int floatforloop (StkId ra) {
/* /*
** Finish the table access 'val = t[key]'. ** Finish the table access 'val = t[key]'.
** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
** t[k] entry (which must be empty).
*/ */
void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val, void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
int aux) { int hres) {
int loop; /* counter to avoid infinite loops */ int loop; /* counter to avoid infinite loops */
const TValue *tm; /* metamethod */ const TValue *tm; /* metamethod */
for (loop = 0; loop < MAXTAGLOOP; loop++) { for (loop = 0; loop < MAXTAGLOOP; loop++) {
if (aux == HNOTATABLE) { /* 't' is not a table? */ if (hres == HNOTATABLE) { /* 't' is not a table? */
lua_assert(!ttistable(t)); lua_assert(!ttistable(t));
tm = luaT_gettmbyobj(L, t, TM_INDEX); tm = luaT_gettmbyobj(L, t, TM_INDEX);
if (l_unlikely(notm(tm))) if (l_unlikely(notm(tm)))
@ -309,8 +307,8 @@ void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val,
return; return;
} }
t = tm; /* else try to access 'tm[key]' */ t = tm; /* else try to access 'tm[key]' */
luaV_fastget1(t, key, s2v(val), luaH_get1, aux); luaV_fastget(t, key, s2v(val), luaH_get, hres);
if (aux == HOK) if (hres == HOK)
return; /* done */ return; /* done */
/* else repeat (tail call 'luaV_finishget') */ /* else repeat (tail call 'luaV_finishget') */
} }
@ -320,21 +318,17 @@ void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val,
/* /*
** Finish a table assignment 't[key] = val'. ** Finish a table assignment 't[key] = val'.
** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
** to the entry 't[key]', or to a value with an absent key if there
** is no such entry. (The value at 'slot' must be empty, otherwise
** 'luaV_fastget' would have done the job.)
*/ */
void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key, void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
TValue *val, int aux) { TValue *val, int hres) {
int loop; /* counter to avoid infinite loops */ int loop; /* counter to avoid infinite loops */
for (loop = 0; loop < MAXTAGLOOP; loop++) { for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm; /* '__newindex' metamethod */ const TValue *tm; /* '__newindex' metamethod */
if (aux != HNOTATABLE) { /* is 't' a table? */ if (hres != HNOTATABLE) { /* is 't' a table? */
Table *h = hvalue(t); /* save 't' table */ Table *h = hvalue(t); /* save 't' table */
tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
if (tm == NULL) { /* no metamethod? */ if (tm == NULL) { /* no metamethod? */
luaH_finishset1(L, h, key, val, aux); /* set new value */ luaH_finishset(L, h, key, val, hres); /* set new value */
invalidateTMcache(h); invalidateTMcache(h);
luaC_barrierback(L, obj2gco(h), val); luaC_barrierback(L, obj2gco(h), val);
return; return;
@ -352,8 +346,8 @@ void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key,
return; return;
} }
t = tm; /* else repeat assignment over 'tm' */ t = tm; /* else repeat assignment over 'tm' */
luaV_fastset1(t, key, val, aux, luaH_set1); luaV_fastset(t, key, val, hres, luaH_pset);
if (aux == HOK) if (hres == HOK)
return; /* done */ return; /* done */
/* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */
} }
@ -1249,36 +1243,36 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
TValue *upval = cl->upvals[GETARG_B(i)]->v.p; TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
TValue *rc = KC(i); TValue *rc = KC(i);
TString *key = tsvalue(rc); /* key must be a string */ TString *key = tsvalue(rc); /* key must be a string */
int aux; int hres;
luaV_fastget1(upval, key, s2v(ra), luaH_getshortstr1, aux); luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres);
if (aux != HOK) if (hres != HOK)
Protect(luaV_finishget1(L, upval, rc, ra, aux)); Protect(luaV_finishget(L, upval, rc, ra, hres));
vmbreak; vmbreak;
} }
vmcase(OP_GETTABLE) { vmcase(OP_GETTABLE) {
StkId ra = RA(i); StkId ra = RA(i);
TValue *rb = vRB(i); TValue *rb = vRB(i);
TValue *rc = vRC(i); TValue *rc = vRC(i);
int aux; int hres;
if (ttisinteger(rc)) { /* fast track for integers? */ if (ttisinteger(rc)) { /* fast track for integers? */
luaV_fastgeti1(rb, ivalue(rc), s2v(ra), aux); luaV_fastgeti(rb, ivalue(rc), s2v(ra), hres);
} }
else else
luaV_fastget1(rb, rc, s2v(ra), luaH_get1, aux); luaV_fastget(rb, rc, s2v(ra), luaH_get, hres);
if (aux != HOK) /* fast track for integers? */ if (hres != HOK) /* fast track for integers? */
Protect(luaV_finishget1(L, rb, rc, ra, aux)); Protect(luaV_finishget(L, rb, rc, ra, hres));
vmbreak; vmbreak;
} }
vmcase(OP_GETI) { vmcase(OP_GETI) {
StkId ra = RA(i); StkId ra = RA(i);
TValue *rb = vRB(i); TValue *rb = vRB(i);
int c = GETARG_C(i); int c = GETARG_C(i);
int aux; int hres;
luaV_fastgeti1(rb, c, s2v(ra), aux); luaV_fastgeti(rb, c, s2v(ra), hres);
if (aux != HOK) { if (hres != HOK) {
TValue key; TValue key;
setivalue(&key, c); setivalue(&key, c);
Protect(luaV_finishget1(L, rb, &key, ra, aux)); Protect(luaV_finishget(L, rb, &key, ra, hres));
} }
vmbreak; vmbreak;
} }
@ -1287,68 +1281,68 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
TValue *rb = vRB(i); TValue *rb = vRB(i);
TValue *rc = KC(i); TValue *rc = KC(i);
TString *key = tsvalue(rc); /* key must be a string */ TString *key = tsvalue(rc); /* key must be a string */
int aux; int hres;
luaV_fastget1(rb, key, s2v(ra), luaH_getshortstr1, aux); luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres);
if (aux != HOK) if (hres != HOK)
Protect(luaV_finishget1(L, rb, rc, ra, aux)); Protect(luaV_finishget(L, rb, rc, ra, hres));
vmbreak; vmbreak;
} }
vmcase(OP_SETTABUP) { vmcase(OP_SETTABUP) {
int aux; int hres;
TValue *upval = cl->upvals[GETARG_A(i)]->v.p; TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
TValue *rb = KB(i); TValue *rb = KB(i);
TValue *rc = RKC(i); TValue *rc = RKC(i);
TString *key = tsvalue(rb); /* key must be a string */ TString *key = tsvalue(rb); /* key must be a string */
luaV_fastset1(upval, key, rc, aux, luaH_setshortstr1); luaV_fastset(upval, key, rc, hres, luaH_psetshortstr);
if (aux == HOK) if (hres == HOK)
luaV_finishfastset1(L, upval, rc); luaV_finishfastset(L, upval, rc);
else else
Protect(luaV_finishset1(L, upval, rb, rc, aux)); Protect(luaV_finishset(L, upval, rb, rc, hres));
vmbreak; vmbreak;
} }
vmcase(OP_SETTABLE) { vmcase(OP_SETTABLE) {
StkId ra = RA(i); StkId ra = RA(i);
int aux; int hres;
TValue *rb = vRB(i); /* key (table is in 'ra') */ TValue *rb = vRB(i); /* key (table is in 'ra') */
TValue *rc = RKC(i); /* value */ TValue *rc = RKC(i); /* value */
if (ttisinteger(rb)) { /* fast track for integers? */ if (ttisinteger(rb)) { /* fast track for integers? */
luaV_fastseti1(s2v(ra), ivalue(rb), rc, aux); luaV_fastseti(s2v(ra), ivalue(rb), rc, hres);
} }
else { else {
luaV_fastset1(s2v(ra), rb, rc, aux, luaH_set1); luaV_fastset(s2v(ra), rb, rc, hres, luaH_pset);
} }
if (aux == HOK) if (hres == HOK)
luaV_finishfastset1(L, s2v(ra), rc); luaV_finishfastset(L, s2v(ra), rc);
else else
Protect(luaV_finishset1(L, s2v(ra), rb, rc, aux)); Protect(luaV_finishset(L, s2v(ra), rb, rc, hres));
vmbreak; vmbreak;
} }
vmcase(OP_SETI) { vmcase(OP_SETI) {
StkId ra = RA(i); StkId ra = RA(i);
int aux; int hres;
int b = GETARG_B(i); int b = GETARG_B(i);
TValue *rc = RKC(i); TValue *rc = RKC(i);
luaV_fastseti1(s2v(ra), b, rc, aux); luaV_fastseti(s2v(ra), b, rc, hres);
if (aux == HOK) if (hres == HOK)
luaV_finishfastset1(L, s2v(ra), rc); luaV_finishfastset(L, s2v(ra), rc);
else { else {
TValue key; TValue key;
setivalue(&key, b); setivalue(&key, b);
Protect(luaV_finishset1(L, s2v(ra), &key, rc, aux)); Protect(luaV_finishset(L, s2v(ra), &key, rc, hres));
} }
vmbreak; vmbreak;
} }
vmcase(OP_SETFIELD) { vmcase(OP_SETFIELD) {
StkId ra = RA(i); StkId ra = RA(i);
int aux; int hres;
TValue *rb = KB(i); TValue *rb = KB(i);
TValue *rc = RKC(i); TValue *rc = RKC(i);
TString *key = tsvalue(rb); /* key must be a string */ TString *key = tsvalue(rb); /* key must be a string */
luaV_fastset1(s2v(ra), key, rc, aux, luaH_setshortstr1); luaV_fastset(s2v(ra), key, rc, hres, luaH_psetshortstr);
if (aux == HOK) if (hres == HOK)
luaV_finishfastset1(L, s2v(ra), rc); luaV_finishfastset(L, s2v(ra), rc);
else else
Protect(luaV_finishset1(L, s2v(ra), rb, rc, aux)); Protect(luaV_finishset(L, s2v(ra), rb, rc, hres));
vmbreak; vmbreak;
} }
vmcase(OP_NEWTABLE) { vmcase(OP_NEWTABLE) {
@ -1372,14 +1366,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
} }
vmcase(OP_SELF) { vmcase(OP_SELF) {
StkId ra = RA(i); StkId ra = RA(i);
int aux; int hres;
TValue *rb = vRB(i); TValue *rb = vRB(i);
TValue *rc = RKC(i); TValue *rc = RKC(i);
TString *key = tsvalue(rc); /* key must be a string */ TString *key = tsvalue(rc); /* key must be a string */
setobj2s(L, ra + 1, rb); setobj2s(L, ra + 1, rb);
luaV_fastget1(rb, key, s2v(ra), luaH_getstr1, aux); luaV_fastget(rb, key, s2v(ra), luaH_getstr, hres);
if (aux != HOK) if (hres != HOK)
Protect(luaV_finishget1(L, rb, rc, ra, aux)); Protect(luaV_finishget(L, rb, rc, ra, hres));
vmbreak; vmbreak;
} }
vmcase(OP_ADDI) { vmcase(OP_ADDI) {

49
lvm.h

@ -76,20 +76,9 @@ typedef enum {
/* /*
** fast track for 'gettable': if 't' is a table and 't[k]' is present, ** fast track for 'gettable'
** return 1 with 'slot' pointing to 't[k]' (position of final result).
** Otherwise, return 0 (meaning it will have to check metamethod)
** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL
** (otherwise). 'f' is the raw get function to use.
*/ */
#define luaV_fastget(L,t,k,slot,f) \ #define luaV_fastget(t,k,res,f, aux) \
(!ttistable(t) \
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
: (slot = f(hvalue(t), k), /* else, do raw access */ \
!isempty(slot))) /* result not empty? */
#define luaV_fastget1(t,k,res,f, aux) \
(aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res))) (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res)))
@ -97,45 +86,33 @@ typedef enum {
** Special case of 'luaV_fastget' for integers, inlining the fast case ** Special case of 'luaV_fastget' for integers, inlining the fast case
** of 'luaH_getint'. ** of 'luaH_getint'.
*/ */
#define luaV_fastgeti(L,t,k,slot) \ #define luaV_fastgeti(t,k,res,aux) \
(!ttistable(t) \
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
: (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \
? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \
!isempty(slot))) /* result not empty? */
#define luaV_fastgeti1(t,k,res,aux) \
if (!ttistable(t)) aux = HNOTATABLE; \ if (!ttistable(t)) aux = HNOTATABLE; \
else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \ else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \
if ((u - 1u < h->alimit)) { \ if ((u - 1u < h->alimit)) { \
int tag = *getArrTag(h,u); \ int tag = *getArrTag(h,u); \
if (tagisempty(tag)) aux = HNOTFOUND; \ if (tagisempty(tag)) aux = HNOTFOUND; \
else { arr2val(h, u, tag, res); aux = HOK; }} \ else { arr2val(h, u, tag, res); aux = HOK; }} \
else { aux = luaH_getint1(h, u, res); }} else { aux = luaH_getint(h, u, res); }}
#define luaV_fastset1(t,k,val,aux,f) \ #define luaV_fastset(t,k,val,aux,f) \
(aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val))) (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val)))
#define luaV_fastseti1(t,k,val,aux) \ #define luaV_fastseti(t,k,val,aux) \
if (!ttistable(t)) aux = HNOTATABLE; \ if (!ttistable(t)) aux = HNOTATABLE; \
else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \ else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \
if ((u - 1u < h->alimit)) { \ if ((u - 1u < h->alimit)) { \
lu_byte *tag = getArrTag(h,u); \ lu_byte *tag = getArrTag(h,u); \
if (tagisempty(*tag)) aux = ~cast_int(u); \ if (tagisempty(*tag)) aux = ~cast_int(u); \
else { val2arr(h, u, tag, val); aux = HOK; }} \ else { val2arr(h, u, tag, val); aux = HOK; }} \
else { aux = luaH_setint1(h, u, val); }} else { aux = luaH_psetint(h, u, val); }}
/* /*
** Finish a fast set operation (when fast get succeeds). In that case, ** Finish a fast set operation (when fast set succeeds).
** 'slot' points to the place to put the value.
*/ */
#define luaV_finishfastset(L,t,slot,v) \ #define luaV_finishfastset(L,t,v) luaC_barrierback(L, gcvalue(t), v)
{ setobj2t(L, cast(TValue *,slot), v); \
luaC_barrierback(L, gcvalue(t), v); }
#define luaV_finishfastset1(L,t,v) luaC_barrierback(L, gcvalue(t), v)
/* /*
@ -153,10 +130,10 @@ LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode);
LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p,
F2Imod mode); F2Imod mode);
LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode);
LUAI_FUNC void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
StkId val, int aux); StkId val, int aux);
LUAI_FUNC void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key, LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
TValue *val, int aux); TValue *val, int aux);
LUAI_FUNC void luaV_finishOp (lua_State *L); LUAI_FUNC void luaV_finishOp (lua_State *L);
LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci);
LUAI_FUNC void luaV_concat (lua_State *L, int total); LUAI_FUNC void luaV_concat (lua_State *L, int total);

Loading…
Cancel
Save