Skip to content

Commit

Permalink
Fixed behavior of table length to be like Cobalt
Browse files Browse the repository at this point in the history
  • Loading branch information
MCJack123 committed Apr 14, 2021
1 parent 3ebc137 commit 5517747
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 16 deletions.
3 changes: 2 additions & 1 deletion include/lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
LUA_API size_t (lua_objlen) (lua_State *L, int idx);
LUA_API size_t (lua_objlen) (lua_State *L, int idx); // Cobalt-compatible length
LUA_API size_t (lua_totalobjlen) (lua_State *L, int idx); // PUC-compatible length
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
Expand Down
26 changes: 26 additions & 0 deletions src/lapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,32 @@ LUA_API size_t lua_objlen (lua_State *L, int idx) {
}
}

LUA_API size_t lua_totalobjlen (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TSTRING: return tsvalue(o)->len;
case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: {
Table* t = hvalue(o);
size_t n;
for (n = t->sizearray; n > 0; --n) {
if (ttype(luaH_getnum(t, n)) != LUA_TNIL) {
return n;
}
}
return 0;
}
case LUA_TNUMBER: {
size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */
l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
lua_unlock(L);
return l;
}
default: return 0;
}
}


LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
Expand Down
2 changes: 1 addition & 1 deletion src/lauxlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ LUALIB_API int luaL_igetn (lua_State *L, int t, int ictx) {
}
lua_pop(L, 2);
}
return (int)lua_objlen(L, t);
return (int)lua_totalobjlen(L, t);
}

#endif
Expand Down
28 changes: 15 additions & 13 deletions src/ltable.c
Original file line number Diff line number Diff line change
Expand Up @@ -558,21 +558,23 @@ static int unbound_search (Table *t, unsigned int j) {
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
int luaH_getn (Table *t) {
unsigned int j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0;
while (j - i > 1) {
unsigned int m = (i+j)/2;
if (ttisnil(&t->array[m - 1])) j = m;
else i = m;
/* Algorithm from Cobalt */
unsigned int a = t->sizearray;
unsigned int n, m = 0;
n = a + 1;
while (ttype(luaH_getnum(t, n)) != LUA_TNIL) {
m = n;
n += a + sizenode(t) + 1;
}
while (n > m + 1) {
unsigned int k = (n + m) / 2;
if (ttype(luaH_getnum(t, k)) != LUA_TNIL) {
m = k;
} else {
n = k;
}
return i;
}
/* else must find a boundary in hash part */
else if (t->node == dummynode) /* hash part is empty? */
return j; /* that is easy... */
else return unbound_search(t, j);
return m;
}


Expand Down
3 changes: 2 additions & 1 deletion src/lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
LUA_API size_t (lua_objlen) (lua_State *L, int idx);
LUA_API size_t (lua_objlen) (lua_State *L, int idx); // Cobalt-compatible length
LUA_API size_t (lua_totalobjlen) (lua_State *L, int idx); // PUC-compatible length
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
Expand Down

0 comments on commit 5517747

Please sign in to comment.