mirror of
https://github.com/lua/lua.git
synced 2025-07-04 15:09:38 +00:00
'luaH_get' functions return tag of the result
Undoing previous commit. Returning TValue increases code size without any visible gains. Returning the tag is a little simpler than returning a special code (HOK/HNOTFOUND) and the tag is useful by itself in some cases.
This commit is contained in:
parent
ce6f5502c9
commit
0593256707
10 changed files with 139 additions and 133 deletions
69
lapi.c
69
lapi.c
|
@ -353,7 +353,7 @@ LUA_API void lua_arith (lua_State *L, int op) {
|
||||||
}
|
}
|
||||||
/* first operand at top - 2, second at top - 1; result go to top - 2 */
|
/* first operand at top - 2, second at top - 1; result go to top - 2 */
|
||||||
luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
|
luaO_arith(L, op, s2v(L->top.p - 2), s2v(L->top.p - 1), L->top.p - 2);
|
||||||
L->top.p--; /* remove second operand */
|
L->top.p--; /* pop second operand */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,47 +666,49 @@ LUA_API int lua_pushthread (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
TValue aux;
|
int tag;
|
||||||
TString *str = luaS_new(L, k);
|
TString *str = luaS_new(L, k);
|
||||||
luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, aux);
|
luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, tag);
|
||||||
if (!isemptyV(aux)) {
|
if (!tagisempty(tag)) {
|
||||||
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_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, aux);
|
tag = luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, tag);
|
||||||
}
|
}
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top.p - 1));
|
return novariant(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static TValue getGlobalTable (lua_State *L) {
|
static void getGlobalTable (lua_State *L, TValue *gt) {
|
||||||
Table *registry = hvalue(&G(L)->l_registry);
|
Table *registry = hvalue(&G(L)->l_registry);
|
||||||
return luaH_getint(registry, LUA_RIDX_GLOBALS);
|
int tag = luaH_getint(registry, LUA_RIDX_GLOBALS, gt);
|
||||||
|
(void)tag; /* avoid not-used warnings when checks are off */
|
||||||
|
api_check(L, novariant(tag) == LUA_TTABLE, "global table must exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API int lua_getglobal (lua_State *L, const char *name) {
|
LUA_API int lua_getglobal (lua_State *L, const char *name) {
|
||||||
TValue gt;
|
TValue gt;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
gt = getGlobalTable(L);
|
getGlobalTable(L, >);
|
||||||
return auxgetstr(L, >, name);
|
return auxgetstr(L, >, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API int lua_gettable (lua_State *L, int idx) {
|
LUA_API int lua_gettable (lua_State *L, int idx) {
|
||||||
TValue aux;
|
int tag;
|
||||||
TValue *t;
|
TValue *t;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checkpop(L, 1);
|
api_checkpop(L, 1);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, aux);
|
luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, tag);
|
||||||
if (isemptyV(aux))
|
if (tagisempty(tag))
|
||||||
luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, aux);
|
tag = luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, tag);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top.p - 1));
|
return novariant(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -718,29 +720,27 @@ 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;
|
||||||
TValue aux;
|
int tag;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = index2value(L, idx);
|
t = index2value(L, idx);
|
||||||
luaV_fastgeti(t, n, s2v(L->top.p), aux);
|
luaV_fastgeti(t, n, s2v(L->top.p), tag);
|
||||||
if (isemptyV(aux)) {
|
if (tagisempty(tag)) {
|
||||||
TValue key;
|
TValue key;
|
||||||
setivalue(&key, n);
|
setivalue(&key, n);
|
||||||
luaV_finishget(L, t, &key, L->top.p, aux);
|
tag = luaV_finishget(L, t, &key, L->top.p, tag);
|
||||||
}
|
}
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttype(s2v(L->top.p - 1));
|
return novariant(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
l_sinline int finishrawget (lua_State *L, TValue res) {
|
static int finishrawget (lua_State *L, int tag) {
|
||||||
if (isemptyV(res)) /* avoid copying empty items to the stack */
|
if (tagisempty(tag)) /* avoid copying empty items to the stack */
|
||||||
setnilvalue(s2v(L->top.p));
|
setnilvalue(s2v(L->top.p));
|
||||||
else
|
|
||||||
setobjV(L, s2v(L->top.p), res);
|
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return ttypeV(res);
|
return novariant(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -753,23 +753,23 @@ l_sinline 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;
|
||||||
TValue res;
|
int tag;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
api_checkpop(L, 1);
|
api_checkpop(L, 1);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
res = luaH_get(t, s2v(L->top.p - 1));
|
tag = luaH_get(t, s2v(L->top.p - 1), s2v(L->top.p - 1));
|
||||||
L->top.p--; /* pop key */
|
L->top.p--; /* pop key */
|
||||||
return finishrawget(L, res);
|
return finishrawget(L, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
|
LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
|
||||||
Table *t;
|
Table *t;
|
||||||
TValue aux;
|
int tag;
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
t = gettable(L, idx);
|
t = gettable(L, idx);
|
||||||
luaH_fastgeti(t, n, s2v(L->top.p), aux);
|
luaH_fastgeti(t, n, s2v(L->top.p), tag);
|
||||||
return finishrawget(L, aux);
|
return finishrawget(L, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -779,7 +779,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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -872,7 +872,7 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
|
||||||
LUA_API void lua_setglobal (lua_State *L, const char *name) {
|
LUA_API void lua_setglobal (lua_State *L, const char *name) {
|
||||||
TValue gt;
|
TValue gt;
|
||||||
lua_lock(L); /* unlock done in 'auxsetstr' */
|
lua_lock(L); /* unlock done in 'auxsetstr' */
|
||||||
gt = getGlobalTable(L);
|
getGlobalTable(L, >);
|
||||||
auxsetstr(L, >, name);
|
auxsetstr(L, >, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,7 +1122,8 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
|
||||||
LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new function */
|
LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new function */
|
||||||
if (f->nupvalues >= 1) { /* does it have an upvalue? */
|
if (f->nupvalues >= 1) { /* does it have an upvalue? */
|
||||||
/* get global table from registry */
|
/* get global table from registry */
|
||||||
TValue gt = getGlobalTable(L);
|
TValue gt;
|
||||||
|
getGlobalTable(L, >);
|
||||||
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
|
||||||
setobj(L, f->upvals[0]->v.p, >);
|
setobj(L, f->upvals[0]->v.p, >);
|
||||||
luaC_barrier(L, f->upvals[0], >);
|
luaC_barrier(L, f->upvals[0], >);
|
||||||
|
@ -1266,7 +1267,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
|
||||||
if (more)
|
if (more)
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
else /* no more elements */
|
else /* no more elements */
|
||||||
L->top.p -= 1; /* remove key */
|
L->top.p--; /* pop key */
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return more;
|
return more;
|
||||||
}
|
}
|
||||||
|
|
5
lcode.c
5
lcode.c
|
@ -541,11 +541,12 @@ static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
|
||||||
** a function can make some indices wrong.
|
** a function can make some indices wrong.
|
||||||
*/
|
*/
|
||||||
static int addk (FuncState *fs, TValue *key, TValue *v) {
|
static int addk (FuncState *fs, TValue *key, TValue *v) {
|
||||||
|
TValue val;
|
||||||
lua_State *L = fs->ls->L;
|
lua_State *L = fs->ls->L;
|
||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
TValue val = luaH_get(fs->ls->h, key); /* query scanner table */
|
int tag = luaH_get(fs->ls->h, key, &val); /* query scanner table */
|
||||||
int k, oldsize;
|
int k, oldsize;
|
||||||
if (ttisintegerV(val)) { /* is there an index there? */
|
if (tag == LUA_VNUMINT) { /* is there an index there? */
|
||||||
k = cast_int(ivalue(&val));
|
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) &&
|
||||||
|
|
5
ldump.c
5
ldump.c
|
@ -132,8 +132,9 @@ static void dumpString (DumpState *D, TString *ts) {
|
||||||
if (ts == NULL)
|
if (ts == NULL)
|
||||||
dumpSize(D, 0);
|
dumpSize(D, 0);
|
||||||
else {
|
else {
|
||||||
TValue idx = luaH_getstr(D->h, ts);
|
TValue idx;
|
||||||
if (!isemptyV(idx)) { /* string already saved? */
|
int tag = luaH_getstr(D->h, ts, &idx);
|
||||||
|
if (!tagisempty(tag)) { /* string already saved? */
|
||||||
dumpSize(D, 1); /* reuse a saved string */
|
dumpSize(D, 1); /* reuse a saved string */
|
||||||
dumpSize(D, cast_sizet(ivalue(&idx))); /* index of saved string */
|
dumpSize(D, cast_sizet(ivalue(&idx))); /* index of saved string */
|
||||||
}
|
}
|
||||||
|
|
26
lobject.h
26
lobject.h
|
@ -75,7 +75,6 @@ typedef struct TValue {
|
||||||
|
|
||||||
/* raw type tag of a TValue */
|
/* raw type tag of a TValue */
|
||||||
#define rawtt(o) ((o)->tt_)
|
#define rawtt(o) ((o)->tt_)
|
||||||
#define rawttV(o) ((o).tt_)
|
|
||||||
|
|
||||||
/* tag with no variants (bits 0-3) */
|
/* tag with no variants (bits 0-3) */
|
||||||
#define novariant(t) ((t) & 0x0F)
|
#define novariant(t) ((t) & 0x0F)
|
||||||
|
@ -83,18 +82,14 @@ typedef struct TValue {
|
||||||
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
|
||||||
#define withvariant(t) ((t) & 0x3F)
|
#define withvariant(t) ((t) & 0x3F)
|
||||||
#define ttypetag(o) withvariant(rawtt(o))
|
#define ttypetag(o) withvariant(rawtt(o))
|
||||||
#define ttypetagV(o) withvariant(rawttV(o))
|
|
||||||
|
|
||||||
/* type of a TValue */
|
/* type of a TValue */
|
||||||
#define ttype(o) (novariant(rawtt(o)))
|
#define ttype(o) (novariant(rawtt(o)))
|
||||||
#define ttypeV(o) (novariant(rawttV(o)))
|
|
||||||
|
|
||||||
|
|
||||||
/* Macros to test type */
|
/* Macros to test type */
|
||||||
#define checktag(o,t) (rawtt(o) == (t))
|
#define checktag(o,t) (rawtt(o) == (t))
|
||||||
#define checktagV(o,t) (rawttV(o) == (t))
|
|
||||||
#define checktype(o,t) (ttype(o) == (t))
|
#define checktype(o,t) (ttype(o) == (t))
|
||||||
#define checktypeV(o,t) (ttypeV(o) == (t))
|
|
||||||
|
|
||||||
|
|
||||||
/* Macros for internal tests */
|
/* Macros for internal tests */
|
||||||
|
@ -117,7 +112,6 @@ typedef struct TValue {
|
||||||
|
|
||||||
/* set a value's tag */
|
/* set a value's tag */
|
||||||
#define settt_(o,t) ((o)->tt_=(t))
|
#define settt_(o,t) ((o)->tt_=(t))
|
||||||
#define setttV_(o,t) ((o).tt_=(t))
|
|
||||||
|
|
||||||
|
|
||||||
/* main macro to copy values (from 'obj2' to 'obj1') */
|
/* main macro to copy values (from 'obj2' to 'obj1') */
|
||||||
|
@ -126,11 +120,6 @@ typedef struct TValue {
|
||||||
io1->value_ = io2->value_; settt_(io1, io2->tt_); \
|
io1->value_ = io2->value_; settt_(io1, io2->tt_); \
|
||||||
checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); }
|
checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); }
|
||||||
|
|
||||||
#define setobjV(L,obj1,obj2) \
|
|
||||||
{ TValue *io1=(obj1); const TValue io2=(obj2); \
|
|
||||||
io1->value_ = io2.value_; settt_(io1, io2.tt_); \
|
|
||||||
checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Different types of assignments, according to source and destination.
|
** Different types of assignments, according to source and destination.
|
||||||
** (They are mostly equal now, but may be different in the future.)
|
** (They are mostly equal now, but may be different in the future.)
|
||||||
|
@ -199,16 +188,19 @@ typedef union {
|
||||||
/* Value returned for a key not found in a table (absent key) */
|
/* Value returned for a key not found in a table (absent key) */
|
||||||
#define LUA_VABSTKEY makevariant(LUA_TNIL, 2)
|
#define LUA_VABSTKEY makevariant(LUA_TNIL, 2)
|
||||||
|
|
||||||
/* Special "value" to signal that a fast get is accessing a non-table */
|
/* Special variant to signal that a fast get is accessing a non-table */
|
||||||
#define LUA_VNOTABLE makevariant(LUA_TNIL, 3)
|
#define LUA_VNOTABLE makevariant(LUA_TNIL, 3)
|
||||||
|
|
||||||
#define setnotableV(obj) setttV_(obj, LUA_VNOTABLE)
|
|
||||||
|
|
||||||
|
|
||||||
/* macro to test for (any kind of) nil */
|
/* macro to test for (any kind of) nil */
|
||||||
#define ttisnil(v) checktype((v), LUA_TNIL)
|
#define ttisnil(v) checktype((v), LUA_TNIL)
|
||||||
#define ttisnilV(v) checktypeV((v), LUA_TNIL)
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Macro to test the result of a table access. Formally, it should
|
||||||
|
** distinguish between LUA_VEMPTY/LUA_VABSTKEY/LUA_VNOTABLE and
|
||||||
|
** other tags. As currently nil is equivalent to LUA_VEMPTY, it is
|
||||||
|
** simpler to just test whether the value is nil.
|
||||||
|
*/
|
||||||
#define tagisempty(tag) (novariant(tag) == LUA_TNIL)
|
#define tagisempty(tag) (novariant(tag) == LUA_TNIL)
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,7 +226,6 @@ typedef union {
|
||||||
** be accepted as empty.)
|
** be accepted as empty.)
|
||||||
*/
|
*/
|
||||||
#define isempty(v) ttisnil(v)
|
#define isempty(v) ttisnil(v)
|
||||||
#define isemptyV(v) checktypeV((v), LUA_TNIL)
|
|
||||||
|
|
||||||
|
|
||||||
/* macro defining a value corresponding to an absent key */
|
/* macro defining a value corresponding to an absent key */
|
||||||
|
@ -346,7 +337,6 @@ typedef struct GCObject {
|
||||||
#define ttisnumber(o) checktype((o), LUA_TNUMBER)
|
#define ttisnumber(o) checktype((o), LUA_TNUMBER)
|
||||||
#define ttisfloat(o) checktag((o), LUA_VNUMFLT)
|
#define ttisfloat(o) checktag((o), LUA_VNUMFLT)
|
||||||
#define ttisinteger(o) checktag((o), LUA_VNUMINT)
|
#define ttisinteger(o) checktag((o), LUA_VNUMINT)
|
||||||
#define ttisintegerV(o) checktagV((o), LUA_VNUMINT)
|
|
||||||
|
|
||||||
#define nvalue(o) check_exp(ttisnumber(o), \
|
#define nvalue(o) check_exp(ttisnumber(o), \
|
||||||
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
|
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
|
||||||
|
|
50
ltable.c
50
ltable.c
|
@ -904,14 +904,23 @@ static int hashkeyisempty (Table *t, lua_Integer key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TValue luaH_getint (Table *t, lua_Integer key) {
|
static int finishnodeget (const TValue *val, TValue *res) {
|
||||||
if (keyinarray(t, key)) {
|
if (!ttisnil(val)) {
|
||||||
TValue res;
|
setobj(((lua_State*)NULL), res, val);
|
||||||
arr2objV(t, key, res);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
else
|
return ttypetag(val);
|
||||||
return *getintfromhash(t, key);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int luaH_getint (Table *t, lua_Integer key, TValue *res) {
|
||||||
|
if (keyinarray(t, key)) {
|
||||||
|
int tag = *getArrTag(t, key - 1);
|
||||||
|
if (!tagisempty(tag))
|
||||||
|
farr2val(t, key, tag, res);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return finishnodeget(getintfromhash(t, key), res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -934,8 +943,8 @@ const TValue *luaH_Hgetshortstr (Table *t, TString *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TValue luaH_getshortstr (Table *t, TString *key) {
|
int luaH_getshortstr (Table *t, TString *key, TValue *res) {
|
||||||
return *luaH_Hgetshortstr(t, key);
|
return finishnodeget(luaH_Hgetshortstr(t, key), res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -950,8 +959,8 @@ static const TValue *Hgetstr (Table *t, TString *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TValue luaH_getstr (Table *t, TString *key) {
|
int luaH_getstr (Table *t, TString *key, TValue *res) {
|
||||||
return *Hgetstr(t, key);
|
return finishnodeget(Hgetstr(t, key), res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -967,31 +976,34 @@ TString *luaH_getstrkey (Table *t, TString *key) {
|
||||||
/*
|
/*
|
||||||
** main search function
|
** main search function
|
||||||
*/
|
*/
|
||||||
TValue luaH_get (Table *t, const TValue *key) {
|
int luaH_get (Table *t, const TValue *key, TValue *res) {
|
||||||
|
const TValue *slot;
|
||||||
switch (ttypetag(key)) {
|
switch (ttypetag(key)) {
|
||||||
case LUA_VSHRSTR:
|
case LUA_VSHRSTR:
|
||||||
return *luaH_Hgetshortstr(t, tsvalue(key));
|
slot = luaH_Hgetshortstr(t, tsvalue(key));
|
||||||
break;
|
break;
|
||||||
case LUA_VNUMINT:
|
case LUA_VNUMINT:
|
||||||
return luaH_getint(t, ivalue(key));
|
return luaH_getint(t, ivalue(key), res);
|
||||||
case LUA_VNIL:
|
case LUA_VNIL:
|
||||||
return absentkey;
|
slot = &absentkey;
|
||||||
break;
|
break;
|
||||||
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 luaH_getint(t, k, res); /* use specialized version */
|
||||||
/* else... */
|
/* else... */
|
||||||
} /* FALLTHROUGH */
|
} /* FALLTHROUGH */
|
||||||
default:
|
default:
|
||||||
return *getgeneric(t, key, 0);
|
slot = getgeneric(t, key, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
return finishnodeget(slot, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
|
static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
|
||||||
if (!ttisnil(slot)) {
|
if (!ttisnil(slot)) {
|
||||||
setobj(cast(lua_State*, NULL), cast(TValue*, slot), val);
|
setobj(((lua_State*)NULL), cast(TValue*, slot), val);
|
||||||
return HOK; /* success */
|
return HOK; /* success */
|
||||||
}
|
}
|
||||||
else if (isabstkey(slot))
|
else if (isabstkey(slot))
|
||||||
|
@ -1005,7 +1017,7 @@ static int rawfinishnodeset (const TValue *slot, TValue *val) {
|
||||||
if (isabstkey(slot))
|
if (isabstkey(slot))
|
||||||
return 0; /* no slot with that key */
|
return 0; /* no slot with that key */
|
||||||
else {
|
else {
|
||||||
setobj(cast(lua_State*, NULL), cast(TValue*, slot), val);
|
setobj(((lua_State*)NULL), cast(TValue*, slot), val);
|
||||||
return 1; /* success */
|
return 1; /* success */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
ltable.h
29
ltable.h
|
@ -46,11 +46,12 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define luaH_fastgeti(t,k,res,aux) \
|
#define luaH_fastgeti(t,k,res,tag) \
|
||||||
{ Table *h = t; lua_Unsigned u = l_castS2U(k); \
|
{ Table *h = t; lua_Unsigned u = l_castS2U(k); \
|
||||||
if ((u - 1u < h->alimit)) arr2objV(h,u,aux); \
|
if ((u - 1u < h->alimit)) { \
|
||||||
else aux = luaH_getint(h, u); \
|
tag = *getArrTag(h,(u)-1u); \
|
||||||
if (!isemptyV(aux)) setobjV(cast(lua_State*, NULL), res, aux); }
|
if (!tagisempty(tag)) { farr2val(h, u, tag, res); }} \
|
||||||
|
else { tag = luaH_getint(h, u, res); }}
|
||||||
|
|
||||||
|
|
||||||
#define luaH_fastseti(t,k,val,hres) \
|
#define luaH_fastseti(t,k,val,hres) \
|
||||||
|
@ -69,6 +70,8 @@
|
||||||
#define HFIRSTNODE 3
|
#define HFIRSTNODE 3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
** 'luaH_get*' operations set 'res', unless the value is absent, and
|
||||||
|
** return the tag of the result,
|
||||||
** The 'luaH_pset*' (pre-set) operations set the given value and return
|
** The 'luaH_pset*' (pre-set) operations set the given value and return
|
||||||
** HOK, unless the original value is absent. In that case, if the key
|
** HOK, unless the original value is absent. In that case, if the key
|
||||||
** is really absent, they return HNOTFOUND. Otherwise, if there is a
|
** is really absent, they return HNOTFOUND. Otherwise, if there is a
|
||||||
|
@ -85,7 +88,8 @@
|
||||||
/*
|
/*
|
||||||
** The array part of a table is represented by an array of cells.
|
** The array part of a table is represented by an array of cells.
|
||||||
** Each cell is composed of NM tags followed by NM values, so that
|
** Each cell is composed of NM tags followed by NM values, so that
|
||||||
** no space is wasted in padding.
|
** no space is wasted in padding. The last cell may be incomplete,
|
||||||
|
** that is, it may have fewer than NM values.
|
||||||
*/
|
*/
|
||||||
#define NM cast_uint(sizeof(Value))
|
#define NM cast_uint(sizeof(Value))
|
||||||
|
|
||||||
|
@ -105,10 +109,8 @@ struct ArrayCell {
|
||||||
/*
|
/*
|
||||||
** Move TValues to/from arrays, using Lua indices
|
** Move TValues to/from arrays, using Lua indices
|
||||||
*/
|
*/
|
||||||
#define arr2objV(h,k,val) \
|
#define arr2obj(h,k,val) \
|
||||||
((val).tt_ = *getArrTag(h,(k)-1u), (val).value_ = *getArrVal(h,(k)-1u))
|
((val)->tt_ = *getArrTag(h,(k)-1u), (val)->value_ = *getArrVal(h,(k)-1u))
|
||||||
|
|
||||||
#define arr2obj(h,k,val) arr2objV(h,k,*(val))
|
|
||||||
|
|
||||||
#define obj2arr(h,k,val) \
|
#define obj2arr(h,k,val) \
|
||||||
(*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
|
(*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
|
||||||
|
@ -126,11 +128,12 @@ struct ArrayCell {
|
||||||
(*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
|
(*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
|
||||||
|
|
||||||
|
|
||||||
LUAI_FUNC TValue luaH_get (Table *t, const TValue *key);
|
LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res);
|
||||||
LUAI_FUNC TValue luaH_getshortstr (Table *t, TString *key);
|
LUAI_FUNC int luaH_getshortstr (Table *t, TString *key, TValue *res);
|
||||||
LUAI_FUNC TValue luaH_getstr (Table *t, TString *key);
|
LUAI_FUNC int luaH_getstr (Table *t, TString *key, TValue *res);
|
||||||
LUAI_FUNC TValue luaH_getint (Table *t, lua_Integer key);
|
LUAI_FUNC int luaH_getint (Table *t, lua_Integer key, TValue *res);
|
||||||
|
|
||||||
|
/* Special get for metamethods */
|
||||||
LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key);
|
LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key);
|
||||||
|
|
||||||
LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key);
|
LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key);
|
||||||
|
|
6
ltests.c
6
ltests.c
|
@ -1538,7 +1538,8 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
|
||||||
}
|
}
|
||||||
else if EQ("getfield") {
|
else if EQ("getfield") {
|
||||||
int t = getindex;
|
int t = getindex;
|
||||||
lua_getfield(L1, t, getstring);
|
int tp = lua_getfield(L1, t, getstring);
|
||||||
|
lua_assert(tp == lua_type(L1, -1));
|
||||||
}
|
}
|
||||||
else if EQ("getglobal") {
|
else if EQ("getglobal") {
|
||||||
lua_getglobal(L1, getstring);
|
lua_getglobal(L1, getstring);
|
||||||
|
@ -1548,7 +1549,8 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
|
||||||
lua_pushnil(L1);
|
lua_pushnil(L1);
|
||||||
}
|
}
|
||||||
else if EQ("gettable") {
|
else if EQ("gettable") {
|
||||||
lua_gettable(L1, getindex);
|
int tp = lua_gettable(L1, getindex);
|
||||||
|
lua_assert(tp == lua_type(L1, -1));
|
||||||
}
|
}
|
||||||
else if EQ("gettop") {
|
else if EQ("gettop") {
|
||||||
lua_pushinteger(L1, lua_gettop(L1));
|
lua_pushinteger(L1, lua_gettop(L1));
|
||||||
|
|
|
@ -149,7 +149,8 @@ static void loadString (LoadState *S, Proto *p, TString **sl) {
|
||||||
}
|
}
|
||||||
else if (size == 1) { /* previously saved string? */
|
else if (size == 1) { /* previously saved string? */
|
||||||
lua_Integer idx = cast(lua_Integer, loadSize(S)); /* get its index */
|
lua_Integer idx = cast(lua_Integer, loadSize(S)); /* get its index */
|
||||||
TValue stv = luaH_getint(S->h, idx); /* get its value */
|
TValue stv;
|
||||||
|
luaH_getint(S->h, idx, &stv); /* get its value */
|
||||||
*sl = ts = tsvalue(&stv);
|
*sl = ts = tsvalue(&stv);
|
||||||
luaC_objbarrier(L, p, ts);
|
luaC_objbarrier(L, p, ts);
|
||||||
return; /* do not save it again */
|
return; /* do not save it again */
|
||||||
|
|
61
lvm.c
61
lvm.c
|
@ -285,13 +285,12 @@ static int floatforloop (StkId ra) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Finish the table access 'val = t[key]'.
|
** Finish the table access 'val = t[key]' and return the tag of the result.
|
||||||
*/
|
*/
|
||||||
void luaV_finishget_ (lua_State *L, const TValue *t, TValue *key, StkId val,
|
int luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
|
||||||
int tag) {
|
int tag) {
|
||||||
int loop; /* counter to avoid infinite loops */
|
int loop; /* counter to avoid infinite loops */
|
||||||
const TValue *tm; /* metamethod */
|
const TValue *tm; /* metamethod */
|
||||||
TValue aux;
|
|
||||||
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
for (loop = 0; loop < MAXTAGLOOP; loop++) {
|
||||||
if (tag == LUA_VNOTABLE) { /* 't' is not a table? */
|
if (tag == LUA_VNOTABLE) { /* 't' is not a table? */
|
||||||
lua_assert(!ttistable(t));
|
lua_assert(!ttistable(t));
|
||||||
|
@ -304,22 +303,22 @@ void luaV_finishget_ (lua_State *L, const TValue *t, TValue *key, StkId val,
|
||||||
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
|
tm = fasttm(L, hvalue(t)->metatable, TM_INDEX); /* table's metamethod */
|
||||||
if (tm == NULL) { /* no metamethod? */
|
if (tm == NULL) { /* no metamethod? */
|
||||||
setnilvalue(s2v(val)); /* result is nil */
|
setnilvalue(s2v(val)); /* result is nil */
|
||||||
return;
|
return LUA_VNIL;
|
||||||
}
|
}
|
||||||
/* else will try the metamethod */
|
/* else will try the metamethod */
|
||||||
}
|
}
|
||||||
if (ttisfunction(tm)) { /* is metamethod a function? */
|
if (ttisfunction(tm)) { /* is metamethod a function? */
|
||||||
luaT_callTMres(L, tm, t, key, val); /* call it */
|
luaT_callTMres(L, tm, t, key, val); /* call it */
|
||||||
return;
|
return ttypetag(s2v(val));
|
||||||
}
|
}
|
||||||
t = tm; /* else try to access 'tm[key]' */
|
t = tm; /* else try to access 'tm[key]' */
|
||||||
luaV_fastget(t, key, s2v(val), luaH_get, aux);
|
luaV_fastget(t, key, s2v(val), luaH_get, tag);
|
||||||
if (!isemptyV(aux))
|
if (!tagisempty(tag))
|
||||||
return; /* done */
|
return tag; /* done */
|
||||||
/* else repeat (tail call 'luaV_finishget') */
|
/* else repeat (tail call 'luaV_finishget') */
|
||||||
tag = ttypetagV(aux);
|
|
||||||
}
|
}
|
||||||
luaG_runerror(L, "'__index' chain too long; possible loop");
|
luaG_runerror(L, "'__index' chain too long; possible loop");
|
||||||
|
return 0; /* to avoid warnings */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1247,36 +1246,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 short string */
|
TString *key = tsvalue(rc); /* key must be a short string */
|
||||||
TValue aux;
|
int tag;
|
||||||
luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, aux);
|
luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, tag);
|
||||||
if (isemptyV(aux))
|
if (tagisempty(tag))
|
||||||
Protect(luaV_finishget(L, upval, rc, ra, aux));
|
Protect(luaV_finishget(L, upval, rc, ra, tag));
|
||||||
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);
|
||||||
TValue aux;
|
int tag;
|
||||||
if (ttisinteger(rc)) { /* fast track for integers? */
|
if (ttisinteger(rc)) { /* fast track for integers? */
|
||||||
luaV_fastgeti(rb, ivalue(rc), s2v(ra), aux);
|
luaV_fastgeti(rb, ivalue(rc), s2v(ra), tag);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
luaV_fastget(rb, rc, s2v(ra), luaH_get, aux);
|
luaV_fastget(rb, rc, s2v(ra), luaH_get, tag);
|
||||||
if (isemptyV(aux)) /* fast track for integers? */
|
if (tagisempty(tag))
|
||||||
Protect(luaV_finishget(L, rb, rc, ra, aux));
|
Protect(luaV_finishget(L, rb, rc, ra, tag));
|
||||||
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);
|
||||||
TValue aux;
|
int tag;
|
||||||
luaV_fastgeti(rb, c, s2v(ra), aux);
|
luaV_fastgeti(rb, c, s2v(ra), tag);
|
||||||
if (isemptyV(aux)) {
|
if (tagisempty(tag)) {
|
||||||
TValue key;
|
TValue key;
|
||||||
setivalue(&key, c);
|
setivalue(&key, c);
|
||||||
Protect(luaV_finishget(L, rb, &key, ra, aux));
|
Protect(luaV_finishget(L, rb, &key, ra, tag));
|
||||||
}
|
}
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
|
@ -1285,10 +1284,10 @@ 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 short string */
|
TString *key = tsvalue(rc); /* key must be a short string */
|
||||||
TValue aux;
|
int tag;
|
||||||
luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, aux);
|
luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, tag);
|
||||||
if (isemptyV(aux))
|
if (tagisempty(tag))
|
||||||
Protect(luaV_finishget(L, rb, rc, ra, aux));
|
Protect(luaV_finishget(L, rb, rc, ra, tag));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_SETTABUP) {
|
vmcase(OP_SETTABUP) {
|
||||||
|
@ -1370,14 +1369,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
||||||
}
|
}
|
||||||
vmcase(OP_SELF) {
|
vmcase(OP_SELF) {
|
||||||
StkId ra = RA(i);
|
StkId ra = RA(i);
|
||||||
TValue aux;
|
int tag;
|
||||||
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_fastget(rb, key, s2v(ra), luaH_getstr, aux);
|
luaV_fastget(rb, key, s2v(ra), luaH_getstr, tag);
|
||||||
if (isemptyV(aux))
|
if (tagisempty(tag))
|
||||||
Protect(luaV_finishget(L, rb, rc, ra, aux));
|
Protect(luaV_finishget(L, rb, rc, ra, tag));
|
||||||
vmbreak;
|
vmbreak;
|
||||||
}
|
}
|
||||||
vmcase(OP_ADDI) {
|
vmcase(OP_ADDI) {
|
||||||
|
|
18
lvm.h
18
lvm.h
|
@ -78,19 +78,17 @@ typedef enum {
|
||||||
/*
|
/*
|
||||||
** fast track for 'gettable'
|
** fast track for 'gettable'
|
||||||
*/
|
*/
|
||||||
#define luaV_fastget(t,k,res,f, aux) \
|
#define luaV_fastget(t,k,res,f, tag) \
|
||||||
{if (!ttistable(t)) setnotableV(aux); \
|
(tag = (!ttistable(t) ? LUA_VNOTABLE : f(hvalue(t), k, res)))
|
||||||
else { aux = f(hvalue(t), k); \
|
|
||||||
if (!isemptyV(aux)) { setobjV(cast(lua_State*, NULL), res, aux); } } }
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** 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(t,k,res,aux) \
|
#define luaV_fastgeti(t,k,res,tag) \
|
||||||
{ if (!ttistable(t)) setnotableV(aux); \
|
if (!ttistable(t)) tag = LUA_VNOTABLE; \
|
||||||
else { luaH_fastgeti(hvalue(t), k, res, aux); } }
|
else { luaH_fastgeti(hvalue(t), k, res, tag); }
|
||||||
|
|
||||||
|
|
||||||
#define luaV_fastset(t,k,val,hres,f) \
|
#define luaV_fastset(t,k,val,hres,f) \
|
||||||
|
@ -122,10 +120,8 @@ 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);
|
||||||
#define luaV_finishget(L,t,key,val,aux) \
|
LUAI_FUNC int luaV_finishget (lua_State *L, const TValue *t, TValue *key,
|
||||||
luaV_finishget_(L,t,key,val,ttypetagV(aux))
|
StkId val, int tag);
|
||||||
LUAI_FUNC void luaV_finishget_ (lua_State *L, const TValue *t, TValue *key,
|
|
||||||
StkId val, int tag);
|
|
||||||
LUAI_FUNC void luaV_finishset (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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue