size of short strings stored in a single byte, to reduce the size
of struct 'TString'
This commit is contained in:
10
lapi.c
10
lapi.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 2.243 2014/11/12 13:28:54 roberto Exp roberto $
|
** $Id: lapi.c,v 2.244 2014/12/26 14:43:45 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -382,15 +382,17 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
|
|||||||
luaO_tostring(L, o);
|
luaO_tostring(L, o);
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
}
|
}
|
||||||
if (len != NULL) *len = tsvalue(o)->len;
|
if (len != NULL)
|
||||||
|
*len = vslen(o);
|
||||||
return svalue(o);
|
return svalue(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
|
||||||
StkId o = index2addr(L, idx);
|
StkId o = index2addr(L, idx);
|
||||||
switch (ttnov(o)) {
|
switch (ttype(o)) {
|
||||||
case LUA_TSTRING: return tsvalue(o)->len;
|
case LUA_TSHRSTR: return tsvalue(o)->shrlen;
|
||||||
|
case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
|
||||||
case LUA_TUSERDATA: return uvalue(o)->len;
|
case LUA_TUSERDATA: return uvalue(o)->len;
|
||||||
case LUA_TTABLE: return luaH_getn(hvalue(o));
|
case LUA_TTABLE: return luaH_getn(hvalue(o));
|
||||||
default: return 0;
|
default: return 0;
|
||||||
|
|||||||
4
ldump.c
4
ldump.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldump.c,v 2.33 2014/07/18 13:36:14 roberto Exp roberto $
|
** $Id: ldump.c,v 2.34 2014/11/02 19:19:04 roberto Exp roberto $
|
||||||
** save precompiled Lua chunks
|
** save precompiled Lua chunks
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -74,7 +74,7 @@ static void DumpString (const TString *s, DumpState *D) {
|
|||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
DumpByte(0, D);
|
DumpByte(0, D);
|
||||||
else {
|
else {
|
||||||
size_t size = s->len + 1; /* include trailing '\0' */
|
size_t size = tsslen(s) + 1; /* include trailing '\0' */
|
||||||
if (size < 0xFF)
|
if (size < 0xFF)
|
||||||
DumpByte(cast_int(size), D);
|
DumpByte(cast_int(size), D);
|
||||||
else {
|
else {
|
||||||
|
|||||||
15
lgc.c
15
lgc.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 2.200 2014/11/02 19:19:04 roberto Exp roberto $
|
** $Id: lgc.c,v 2.201 2014/12/20 13:58:15 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -226,10 +226,14 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
|||||||
reentry:
|
reentry:
|
||||||
white2gray(o);
|
white2gray(o);
|
||||||
switch (o->tt) {
|
switch (o->tt) {
|
||||||
case LUA_TSHRSTR:
|
case LUA_TSHRSTR: {
|
||||||
|
gray2black(o);
|
||||||
|
g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case LUA_TLNGSTR: {
|
case LUA_TLNGSTR: {
|
||||||
gray2black(o);
|
gray2black(o);
|
||||||
g->GCmemtrav += sizestring(gco2ts(o));
|
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_TUSERDATA: {
|
case LUA_TUSERDATA: {
|
||||||
@@ -689,9 +693,10 @@ static void freeobj (lua_State *L, GCObject *o) {
|
|||||||
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
|
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
|
||||||
case LUA_TSHRSTR:
|
case LUA_TSHRSTR:
|
||||||
luaS_remove(L, gco2ts(o)); /* remove it from hash table */
|
luaS_remove(L, gco2ts(o)); /* remove it from hash table */
|
||||||
/* go through */
|
luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
|
||||||
|
break;
|
||||||
case LUA_TLNGSTR: {
|
case LUA_TLNGSTR: {
|
||||||
luaM_freemem(L, o, sizestring(gco2ts(o)));
|
luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: lua_assert(0);
|
default: lua_assert(0);
|
||||||
|
|||||||
13
lobject.h
13
lobject.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 2.105 2014/12/19 13:36:32 roberto Exp roberto $
|
** $Id: lobject.h,v 2.106 2015/01/05 13:52:37 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -303,9 +303,12 @@ typedef TValue *StkId; /* index to stack elements */
|
|||||||
typedef struct TString {
|
typedef struct TString {
|
||||||
CommonHeader;
|
CommonHeader;
|
||||||
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
|
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
|
||||||
|
lu_byte shrlen; /* length for short strings */
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
size_t len; /* number of characters in string */
|
union {
|
||||||
|
size_t lnglen; /* length for long strings */
|
||||||
struct TString *hnext; /* linked list for hash table */
|
struct TString *hnext; /* linked list for hash table */
|
||||||
|
} u;
|
||||||
} TString;
|
} TString;
|
||||||
|
|
||||||
|
|
||||||
@@ -329,6 +332,12 @@ typedef union UTString {
|
|||||||
/* get the actual string (array of bytes) from a Lua value */
|
/* get the actual string (array of bytes) from a Lua value */
|
||||||
#define svalue(o) getstr(tsvalue(o))
|
#define svalue(o) getstr(tsvalue(o))
|
||||||
|
|
||||||
|
/* get string length from 'TString *s' */
|
||||||
|
#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
|
||||||
|
|
||||||
|
/* get string length from 'TValue *o' */
|
||||||
|
#define vslen(o) tsslen(tsvalue(o))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Header for userdata; memory area follows the end of this structure
|
** Header for userdata; memory area follows the end of this structure
|
||||||
|
|||||||
27
lstring.c
27
lstring.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.c,v 2.44 2014/07/21 16:02:10 roberto Exp roberto $
|
** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp roberto $
|
||||||
** String table (keeps all strings handled by Lua)
|
** String table (keeps all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
** equality for long strings
|
** equality for long strings
|
||||||
*/
|
*/
|
||||||
int luaS_eqlngstr (TString *a, TString *b) {
|
int luaS_eqlngstr (TString *a, TString *b) {
|
||||||
size_t len = a->len;
|
size_t len = a->u.lnglen;
|
||||||
lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
|
lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
|
||||||
return (a == b) || /* same instance or... */
|
return (a == b) || /* same instance or... */
|
||||||
((len == b->len) && /* equal length and ... */
|
((len == b->u.lnglen) && /* equal length and ... */
|
||||||
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
|
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,9 +69,9 @@ void luaS_resize (lua_State *L, int newsize) {
|
|||||||
TString *p = tb->hash[i];
|
TString *p = tb->hash[i];
|
||||||
tb->hash[i] = NULL;
|
tb->hash[i] = NULL;
|
||||||
while (p) { /* for each node in the list */
|
while (p) { /* for each node in the list */
|
||||||
TString *hnext = p->hnext; /* save next */
|
TString *hnext = p->u.hnext; /* save next */
|
||||||
unsigned int h = lmod(p->hash, newsize); /* new position */
|
unsigned int h = lmod(p->hash, newsize); /* new position */
|
||||||
p->hnext = tb->hash[h]; /* chain it */
|
p->u.hnext = tb->hash[h]; /* chain it */
|
||||||
tb->hash[h] = p;
|
tb->hash[h] = p;
|
||||||
p = hnext;
|
p = hnext;
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,6 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
|
|||||||
totalsize = sizelstring(l);
|
totalsize = sizelstring(l);
|
||||||
o = luaC_newobj(L, tag, totalsize);
|
o = luaC_newobj(L, tag, totalsize);
|
||||||
ts = gco2ts(o);
|
ts = gco2ts(o);
|
||||||
ts->len = l;
|
|
||||||
ts->hash = h;
|
ts->hash = h;
|
||||||
ts->extra = 0;
|
ts->extra = 0;
|
||||||
memcpy(getaddrstr(ts), str, l * sizeof(char));
|
memcpy(getaddrstr(ts), str, l * sizeof(char));
|
||||||
@@ -110,8 +109,8 @@ void luaS_remove (lua_State *L, TString *ts) {
|
|||||||
stringtable *tb = &G(L)->strt;
|
stringtable *tb = &G(L)->strt;
|
||||||
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
|
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
|
||||||
while (*p != ts) /* find previous element */
|
while (*p != ts) /* find previous element */
|
||||||
p = &(*p)->hnext;
|
p = &(*p)->u.hnext;
|
||||||
*p = (*p)->hnext; /* remove element from its list */
|
*p = (*p)->u.hnext; /* remove element from its list */
|
||||||
tb->nuse--;
|
tb->nuse--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,8 +123,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
|
|||||||
global_State *g = G(L);
|
global_State *g = G(L);
|
||||||
unsigned int h = luaS_hash(str, l, g->seed);
|
unsigned int h = luaS_hash(str, l, g->seed);
|
||||||
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
|
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
|
||||||
for (ts = *list; ts != NULL; ts = ts->hnext) {
|
for (ts = *list; ts != NULL; ts = ts->u.hnext) {
|
||||||
if (l == ts->len &&
|
if (l == ts->shrlen &&
|
||||||
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
|
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
|
||||||
/* found! */
|
/* found! */
|
||||||
if (isdead(g, ts)) /* dead (but not collected yet)? */
|
if (isdead(g, ts)) /* dead (but not collected yet)? */
|
||||||
@@ -138,7 +137,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
|
|||||||
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
|
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
|
||||||
}
|
}
|
||||||
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
|
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
|
||||||
ts->hnext = *list;
|
ts->shrlen = cast_byte(l);
|
||||||
|
ts->u.hnext = *list;
|
||||||
*list = ts;
|
*list = ts;
|
||||||
g->strt.nuse++;
|
g->strt.nuse++;
|
||||||
return ts;
|
return ts;
|
||||||
@@ -152,9 +152,12 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
|||||||
if (l <= LUAI_MAXSHORTLEN) /* short string? */
|
if (l <= LUAI_MAXSHORTLEN) /* short string? */
|
||||||
return internshrstr(L, str, l);
|
return internshrstr(L, str, l);
|
||||||
else {
|
else {
|
||||||
|
TString *ts;
|
||||||
if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
|
if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
|
||||||
luaM_toobig(L);
|
luaM_toobig(L);
|
||||||
return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
|
ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
|
||||||
|
ts->u.lnglen = l;
|
||||||
|
return ts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp roberto $
|
** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp roberto $
|
||||||
** String table (keep all strings handled by Lua)
|
** String table (keep all strings handled by Lua)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
|
#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
|
||||||
#define sizestring(s) sizelstring((s)->len)
|
|
||||||
|
|
||||||
#define sizeludata(l) (sizeof(union UUdata) + (l))
|
#define sizeludata(l) (sizeof(union UUdata) + (l))
|
||||||
#define sizeudata(u) sizeludata((u)->len)
|
#define sizeudata(u) sizeludata((u)->len)
|
||||||
|
|||||||
4
ltable.c
4
ltable.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.c,v 2.99 2014/11/02 19:19:04 roberto Exp roberto $
|
** $Id: ltable.c,v 2.100 2015/01/05 13:52:37 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -127,7 +127,7 @@ static Node *mainposition (const Table *t, const TValue *key) {
|
|||||||
case LUA_TLNGSTR: {
|
case LUA_TLNGSTR: {
|
||||||
TString *s = tsvalue(key);
|
TString *s = tsvalue(key);
|
||||||
if (s->extra == 0) { /* no hash? */
|
if (s->extra == 0) { /* no hash? */
|
||||||
s->hash = luaS_hash(getstr(s), s->len, s->hash);
|
s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash);
|
||||||
s->extra = 1; /* now it has its hash */
|
s->extra = 1; /* now it has its hash */
|
||||||
}
|
}
|
||||||
return hashstr(t, tsvalue(key));
|
return hashstr(t, tsvalue(key));
|
||||||
|
|||||||
4
ltests.c
4
ltests.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltests.c,v 2.200 2014/12/10 11:30:51 roberto Exp roberto $
|
** $Id: ltests.c,v 2.201 2014/12/18 12:13:42 roberto Exp roberto $
|
||||||
** Internal Module for Debugging of the Lua Implementation
|
** Internal Module for Debugging of the Lua Implementation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -724,7 +724,7 @@ static int string_query (lua_State *L) {
|
|||||||
else if (s < tb->size) {
|
else if (s < tb->size) {
|
||||||
TString *ts;
|
TString *ts;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (ts = tb->hash[s]; ts != NULL; ts = ts->hnext) {
|
for (ts = tb->hash[s]; ts != NULL; ts = ts->u.hnext) {
|
||||||
setsvalue2s(L, L->top, ts);
|
setsvalue2s(L, L->top, ts);
|
||||||
api_incr_top(L);
|
api_incr_top(L);
|
||||||
n++;
|
n++;
|
||||||
|
|||||||
32
lvm.c
32
lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.231 2014/12/19 13:36:32 roberto Exp roberto $
|
** $Id: lvm.c,v 2.232 2014/12/27 20:30:38 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -73,7 +73,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (cvt2num(obj) && /* string convertible to number? */
|
else if (cvt2num(obj) && /* string convertible to number? */
|
||||||
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
|
luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
|
||||||
*n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
|
*n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -106,7 +106,7 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (cvt2num(obj) &&
|
else if (cvt2num(obj) &&
|
||||||
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
|
luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
|
||||||
obj = &v;
|
obj = &v;
|
||||||
goto again; /* convert result from 'luaO_str2num' to an integer */
|
goto again; /* convert result from 'luaO_str2num' to an integer */
|
||||||
}
|
}
|
||||||
@@ -239,9 +239,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
|||||||
*/
|
*/
|
||||||
static int l_strcmp (const TString *ls, const TString *rs) {
|
static int l_strcmp (const TString *ls, const TString *rs) {
|
||||||
const char *l = getstr(ls);
|
const char *l = getstr(ls);
|
||||||
size_t ll = ls->len;
|
size_t ll = tsslen(ls);
|
||||||
const char *r = getstr(rs);
|
const char *r = getstr(rs);
|
||||||
size_t lr = rs->len;
|
size_t lr = tsslen(rs);
|
||||||
for (;;) { /* for each segment */
|
for (;;) { /* for each segment */
|
||||||
int temp = strcoll(l, r);
|
int temp = strcoll(l, r);
|
||||||
if (temp != 0) /* not equal? */
|
if (temp != 0) /* not equal? */
|
||||||
@@ -354,6 +354,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
|
|||||||
#define tostring(L,o) \
|
#define tostring(L,o) \
|
||||||
(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
|
(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
|
||||||
|
|
||||||
|
#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main operation for concatenation: concat 'total' values in the stack,
|
** Main operation for concatenation: concat 'total' values in the stack,
|
||||||
** from 'L->top - total' up to 'L->top - 1'.
|
** from 'L->top - total' up to 'L->top - 1'.
|
||||||
@@ -365,19 +367,19 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
int n = 2; /* number of elements handled in this pass (at least 2) */
|
int n = 2; /* number of elements handled in this pass (at least 2) */
|
||||||
if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
|
if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
|
||||||
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
|
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
|
||||||
else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
|
else if (isemptystr(top - 1)) /* second operand is empty? */
|
||||||
cast_void(tostring(L, top - 2)); /* result is first operand */
|
cast_void(tostring(L, top - 2)); /* result is first operand */
|
||||||
else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
|
else if (isemptystr(top - 2)) { /* first operand is an empty string? */
|
||||||
setobjs2s(L, top - 2, top - 1); /* result is second op. */
|
setobjs2s(L, top - 2, top - 1); /* result is second op. */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* at least two non-empty string values; get as many as possible */
|
/* at least two non-empty string values; get as many as possible */
|
||||||
size_t tl = tsvalue(top-1)->len;
|
size_t tl = vslen(top - 1);
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int i;
|
int i;
|
||||||
/* collect total length */
|
/* collect total length */
|
||||||
for (i = 1; i < total && tostring(L, top-i-1); i++) {
|
for (i = 1; i < total && tostring(L, top-i-1); i++) {
|
||||||
size_t l = tsvalue(top-i-1)->len;
|
size_t l = vslen(top - i - 1);
|
||||||
if (l >= (MAX_SIZE/sizeof(char)) - tl)
|
if (l >= (MAX_SIZE/sizeof(char)) - tl)
|
||||||
luaG_runerror(L, "string length overflow");
|
luaG_runerror(L, "string length overflow");
|
||||||
tl += l;
|
tl += l;
|
||||||
@@ -386,7 +388,7 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
tl = 0;
|
tl = 0;
|
||||||
n = i;
|
n = i;
|
||||||
do { /* copy all strings to buffer */
|
do { /* copy all strings to buffer */
|
||||||
size_t l = tsvalue(top-i)->len;
|
size_t l = vslen(top - i);
|
||||||
memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
|
memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
|
||||||
tl += l;
|
tl += l;
|
||||||
} while (--i > 0);
|
} while (--i > 0);
|
||||||
@@ -403,7 +405,7 @@ void luaV_concat (lua_State *L, int total) {
|
|||||||
*/
|
*/
|
||||||
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
|
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
|
||||||
const TValue *tm;
|
const TValue *tm;
|
||||||
switch (ttnov(rb)) {
|
switch (ttype(rb)) {
|
||||||
case LUA_TTABLE: {
|
case LUA_TTABLE: {
|
||||||
Table *h = hvalue(rb);
|
Table *h = hvalue(rb);
|
||||||
tm = fasttm(L, h->metatable, TM_LEN);
|
tm = fasttm(L, h->metatable, TM_LEN);
|
||||||
@@ -411,8 +413,12 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
|
|||||||
setivalue(ra, luaH_getn(h)); /* else primitive len */
|
setivalue(ra, luaH_getn(h)); /* else primitive len */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case LUA_TSTRING: {
|
case LUA_TSHRSTR: {
|
||||||
setivalue(ra, tsvalue(rb)->len);
|
setivalue(ra, tsvalue(rb)->shrlen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case LUA_TLNGSTR: {
|
||||||
|
setivalue(ra, tsvalue(rb)->u.lnglen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default: { /* try metamethod */
|
default: { /* try metamethod */
|
||||||
|
|||||||
Reference in New Issue
Block a user