summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c10
-rw-r--r--ldump.c4
-rw-r--r--lgc.c15
-rw-r--r--lobject.h15
-rw-r--r--lstring.c27
-rw-r--r--lstring.h3
-rw-r--r--ltable.c4
-rw-r--r--ltests.c4
-rw-r--r--lvm.c32
9 files changed, 69 insertions, 45 deletions
diff --git a/lapi.c b/lapi.c
index c2ef6019..9d6123ce 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.243 2014/11/12 13:28:54 roberto Exp roberto $ 2** $Id: lapi.c,v 2.244 2014/12/26 14:43:45 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -382,15 +382,17 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
382 luaO_tostring(L, o); 382 luaO_tostring(L, o);
383 lua_unlock(L); 383 lua_unlock(L);
384 } 384 }
385 if (len != NULL) *len = tsvalue(o)->len; 385 if (len != NULL)
386 *len = vslen(o);
386 return svalue(o); 387 return svalue(o);
387} 388}
388 389
389 390
390LUA_API size_t lua_rawlen (lua_State *L, int idx) { 391LUA_API size_t lua_rawlen (lua_State *L, int idx) {
391 StkId o = index2addr(L, idx); 392 StkId o = index2addr(L, idx);
392 switch (ttnov(o)) { 393 switch (ttype(o)) {
393 case LUA_TSTRING: return tsvalue(o)->len; 394 case LUA_TSHRSTR: return tsvalue(o)->shrlen;
395 case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
394 case LUA_TUSERDATA: return uvalue(o)->len; 396 case LUA_TUSERDATA: return uvalue(o)->len;
395 case LUA_TTABLE: return luaH_getn(hvalue(o)); 397 case LUA_TTABLE: return luaH_getn(hvalue(o));
396 default: return 0; 398 default: return 0;
diff --git a/ldump.c b/ldump.c
index a3da9a9f..ec35031e 100644
--- a/ldump.c
+++ b/ldump.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldump.c,v 2.33 2014/07/18 13:36:14 roberto Exp roberto $ 2** $Id: ldump.c,v 2.34 2014/11/02 19:19:04 roberto Exp roberto $
3** save precompiled Lua chunks 3** save precompiled Lua chunks
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -74,7 +74,7 @@ static void DumpString (const TString *s, DumpState *D) {
74 if (s == NULL) 74 if (s == NULL)
75 DumpByte(0, D); 75 DumpByte(0, D);
76 else { 76 else {
77 size_t size = s->len + 1; /* include trailing '\0' */ 77 size_t size = tsslen(s) + 1; /* include trailing '\0' */
78 if (size < 0xFF) 78 if (size < 0xFF)
79 DumpByte(cast_int(size), D); 79 DumpByte(cast_int(size), D);
80 else { 80 else {
diff --git a/lgc.c b/lgc.c
index 185c1d8c..1695ea74 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.200 2014/11/02 19:19:04 roberto Exp roberto $ 2** $Id: lgc.c,v 2.201 2014/12/20 13:58:15 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -226,10 +226,14 @@ static void reallymarkobject (global_State *g, GCObject *o) {
226 reentry: 226 reentry:
227 white2gray(o); 227 white2gray(o);
228 switch (o->tt) { 228 switch (o->tt) {
229 case LUA_TSHRSTR: 229 case LUA_TSHRSTR: {
230 gray2black(o);
231 g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
232 break;
233 }
230 case LUA_TLNGSTR: { 234 case LUA_TLNGSTR: {
231 gray2black(o); 235 gray2black(o);
232 g->GCmemtrav += sizestring(gco2ts(o)); 236 g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
233 break; 237 break;
234 } 238 }
235 case LUA_TUSERDATA: { 239 case LUA_TUSERDATA: {
@@ -689,9 +693,10 @@ static void freeobj (lua_State *L, GCObject *o) {
689 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; 693 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
690 case LUA_TSHRSTR: 694 case LUA_TSHRSTR:
691 luaS_remove(L, gco2ts(o)); /* remove it from hash table */ 695 luaS_remove(L, gco2ts(o)); /* remove it from hash table */
692 /* go through */ 696 luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
697 break;
693 case LUA_TLNGSTR: { 698 case LUA_TLNGSTR: {
694 luaM_freemem(L, o, sizestring(gco2ts(o))); 699 luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
695 break; 700 break;
696 } 701 }
697 default: lua_assert(0); 702 default: lua_assert(0);
diff --git a/lobject.h b/lobject.h
index f98eb812..cb194105 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.105 2014/12/19 13:36:32 roberto Exp roberto $ 2** $Id: lobject.h,v 2.106 2015/01/05 13:52:37 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -303,9 +303,12 @@ typedef TValue *StkId; /* index to stack elements */
303typedef struct TString { 303typedef struct TString {
304 CommonHeader; 304 CommonHeader;
305 lu_byte extra; /* reserved words for short strings; "has hash" for longs */ 305 lu_byte extra; /* reserved words for short strings; "has hash" for longs */
306 lu_byte shrlen; /* length for short strings */
306 unsigned int hash; 307 unsigned int hash;
307 size_t len; /* number of characters in string */ 308 union {
308 struct TString *hnext; /* linked list for hash table */ 309 size_t lnglen; /* length for long strings */
310 struct TString *hnext; /* linked list for hash table */
311 } u;
309} TString; 312} TString;
310 313
311 314
@@ -329,6 +332,12 @@ typedef union UTString {
329/* get the actual string (array of bytes) from a Lua value */ 332/* get the actual string (array of bytes) from a Lua value */
330#define svalue(o) getstr(tsvalue(o)) 333#define svalue(o) getstr(tsvalue(o))
331 334
335/* get string length from 'TString *s' */
336#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
337
338/* get string length from 'TValue *o' */
339#define vslen(o) tsslen(tsvalue(o))
340
332 341
333/* 342/*
334** Header for userdata; memory area follows the end of this structure 343** Header for userdata; memory area follows the end of this structure
diff --git a/lstring.c b/lstring.c
index 27b06dd3..29e4630c 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.c,v 2.44 2014/07/21 16:02:10 roberto Exp roberto $ 2** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp roberto $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -36,10 +36,10 @@
36** equality for long strings 36** equality for long strings
37*/ 37*/
38int luaS_eqlngstr (TString *a, TString *b) { 38int luaS_eqlngstr (TString *a, TString *b) {
39 size_t len = a->len; 39 size_t len = a->u.lnglen;
40 lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); 40 lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
41 return (a == b) || /* same instance or... */ 41 return (a == b) || /* same instance or... */
42 ((len == b->len) && /* equal length and ... */ 42 ((len == b->u.lnglen) && /* equal length and ... */
43 (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ 43 (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
44} 44}
45 45
@@ -69,9 +69,9 @@ void luaS_resize (lua_State *L, int newsize) {
69 TString *p = tb->hash[i]; 69 TString *p = tb->hash[i];
70 tb->hash[i] = NULL; 70 tb->hash[i] = NULL;
71 while (p) { /* for each node in the list */ 71 while (p) { /* for each node in the list */
72 TString *hnext = p->hnext; /* save next */ 72 TString *hnext = p->u.hnext; /* save next */
73 unsigned int h = lmod(p->hash, newsize); /* new position */ 73 unsigned int h = lmod(p->hash, newsize); /* new position */
74 p->hnext = tb->hash[h]; /* chain it */ 74 p->u.hnext = tb->hash[h]; /* chain it */
75 tb->hash[h] = p; 75 tb->hash[h] = p;
76 p = hnext; 76 p = hnext;
77 } 77 }
@@ -97,7 +97,6 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
97 totalsize = sizelstring(l); 97 totalsize = sizelstring(l);
98 o = luaC_newobj(L, tag, totalsize); 98 o = luaC_newobj(L, tag, totalsize);
99 ts = gco2ts(o); 99 ts = gco2ts(o);
100 ts->len = l;
101 ts->hash = h; 100 ts->hash = h;
102 ts->extra = 0; 101 ts->extra = 0;
103 memcpy(getaddrstr(ts), str, l * sizeof(char)); 102 memcpy(getaddrstr(ts), str, l * sizeof(char));
@@ -110,8 +109,8 @@ void luaS_remove (lua_State *L, TString *ts) {
110 stringtable *tb = &G(L)->strt; 109 stringtable *tb = &G(L)->strt;
111 TString **p = &tb->hash[lmod(ts->hash, tb->size)]; 110 TString **p = &tb->hash[lmod(ts->hash, tb->size)];
112 while (*p != ts) /* find previous element */ 111 while (*p != ts) /* find previous element */
113 p = &(*p)->hnext; 112 p = &(*p)->u.hnext;
114 *p = (*p)->hnext; /* remove element from its list */ 113 *p = (*p)->u.hnext; /* remove element from its list */
115 tb->nuse--; 114 tb->nuse--;
116} 115}
117 116
@@ -124,8 +123,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
124 global_State *g = G(L); 123 global_State *g = G(L);
125 unsigned int h = luaS_hash(str, l, g->seed); 124 unsigned int h = luaS_hash(str, l, g->seed);
126 TString **list = &g->strt.hash[lmod(h, g->strt.size)]; 125 TString **list = &g->strt.hash[lmod(h, g->strt.size)];
127 for (ts = *list; ts != NULL; ts = ts->hnext) { 126 for (ts = *list; ts != NULL; ts = ts->u.hnext) {
128 if (l == ts->len && 127 if (l == ts->shrlen &&
129 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { 128 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
130 /* found! */ 129 /* found! */
131 if (isdead(g, ts)) /* dead (but not collected yet)? */ 130 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) {
138 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ 137 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
139 } 138 }
140 ts = createstrobj(L, str, l, LUA_TSHRSTR, h); 139 ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
141 ts->hnext = *list; 140 ts->shrlen = cast_byte(l);
141 ts->u.hnext = *list;
142 *list = ts; 142 *list = ts;
143 g->strt.nuse++; 143 g->strt.nuse++;
144 return ts; 144 return ts;
@@ -152,9 +152,12 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
152 if (l <= LUAI_MAXSHORTLEN) /* short string? */ 152 if (l <= LUAI_MAXSHORTLEN) /* short string? */
153 return internshrstr(L, str, l); 153 return internshrstr(L, str, l);
154 else { 154 else {
155 TString *ts;
155 if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) 156 if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
156 luaM_toobig(L); 157 luaM_toobig(L);
157 return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); 158 ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
159 ts->u.lnglen = l;
160 return ts;
158 } 161 }
159} 162}
160 163
diff --git a/lstring.h b/lstring.h
index e515bf30..573daf9a 100644
--- a/lstring.h
+++ b/lstring.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp roberto $ 2** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp roberto $
3** String table (keep all strings handled by Lua) 3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -13,7 +13,6 @@
13 13
14 14
15#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) 15#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
16#define sizestring(s) sizelstring((s)->len)
17 16
18#define sizeludata(l) (sizeof(union UUdata) + (l)) 17#define sizeludata(l) (sizeof(union UUdata) + (l))
19#define sizeudata(u) sizeludata((u)->len) 18#define sizeudata(u) sizeludata((u)->len)
diff --git a/ltable.c b/ltable.c
index 563ae6de..26b1f773 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.99 2014/11/02 19:19:04 roberto Exp roberto $ 2** $Id: ltable.c,v 2.100 2015/01/05 13:52:37 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -127,7 +127,7 @@ static Node *mainposition (const Table *t, const TValue *key) {
127 case LUA_TLNGSTR: { 127 case LUA_TLNGSTR: {
128 TString *s = tsvalue(key); 128 TString *s = tsvalue(key);
129 if (s->extra == 0) { /* no hash? */ 129 if (s->extra == 0) { /* no hash? */
130 s->hash = luaS_hash(getstr(s), s->len, s->hash); 130 s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash);
131 s->extra = 1; /* now it has its hash */ 131 s->extra = 1; /* now it has its hash */
132 } 132 }
133 return hashstr(t, tsvalue(key)); 133 return hashstr(t, tsvalue(key));
diff --git a/ltests.c b/ltests.c
index 85a7c742..dadcad8d 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.200 2014/12/10 11:30:51 roberto Exp roberto $ 2** $Id: ltests.c,v 2.201 2014/12/18 12:13:42 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -724,7 +724,7 @@ static int string_query (lua_State *L) {
724 else if (s < tb->size) { 724 else if (s < tb->size) {
725 TString *ts; 725 TString *ts;
726 int n = 0; 726 int n = 0;
727 for (ts = tb->hash[s]; ts != NULL; ts = ts->hnext) { 727 for (ts = tb->hash[s]; ts != NULL; ts = ts->u.hnext) {
728 setsvalue2s(L, L->top, ts); 728 setsvalue2s(L, L->top, ts);
729 api_incr_top(L); 729 api_incr_top(L);
730 n++; 730 n++;
diff --git a/lvm.c b/lvm.c
index 1b4357fd..06fc60a4 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.231 2014/12/19 13:36:32 roberto Exp roberto $ 2** $Id: lvm.c,v 2.232 2014/12/27 20:30:38 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -73,7 +73,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
73 return 1; 73 return 1;
74 } 74 }
75 else if (cvt2num(obj) && /* string convertible to number? */ 75 else if (cvt2num(obj) && /* string convertible to number? */
76 luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) { 76 luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
77 *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */ 77 *n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
78 return 1; 78 return 1;
79 } 79 }
@@ -106,7 +106,7 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
106 return 1; 106 return 1;
107 } 107 }
108 else if (cvt2num(obj) && 108 else if (cvt2num(obj) &&
109 luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) { 109 luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
110 obj = &v; 110 obj = &v;
111 goto again; /* convert result from 'luaO_str2num' to an integer */ 111 goto again; /* convert result from 'luaO_str2num' to an integer */
112 } 112 }
@@ -239,9 +239,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
239*/ 239*/
240static int l_strcmp (const TString *ls, const TString *rs) { 240static int l_strcmp (const TString *ls, const TString *rs) {
241 const char *l = getstr(ls); 241 const char *l = getstr(ls);
242 size_t ll = ls->len; 242 size_t ll = tsslen(ls);
243 const char *r = getstr(rs); 243 const char *r = getstr(rs);
244 size_t lr = rs->len; 244 size_t lr = tsslen(rs);
245 for (;;) { /* for each segment */ 245 for (;;) { /* for each segment */
246 int temp = strcoll(l, r); 246 int temp = strcoll(l, r);
247 if (temp != 0) /* not equal? */ 247 if (temp != 0) /* not equal? */
@@ -354,6 +354,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
354#define tostring(L,o) \ 354#define tostring(L,o) \
355 (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) 355 (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
356 356
357#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)
358
357/* 359/*
358** Main operation for concatenation: concat 'total' values in the stack, 360** Main operation for concatenation: concat 'total' values in the stack,
359** from 'L->top - total' up to 'L->top - 1'. 361** from 'L->top - total' up to 'L->top - 1'.
@@ -365,19 +367,19 @@ void luaV_concat (lua_State *L, int total) {
365 int n = 2; /* number of elements handled in this pass (at least 2) */ 367 int n = 2; /* number of elements handled in this pass (at least 2) */
366 if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1)) 368 if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
367 luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT); 369 luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
368 else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ 370 else if (isemptystr(top - 1)) /* second operand is empty? */
369 cast_void(tostring(L, top - 2)); /* result is first operand */ 371 cast_void(tostring(L, top - 2)); /* result is first operand */
370 else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { 372 else if (isemptystr(top - 2)) { /* first operand is an empty string? */
371 setobjs2s(L, top - 2, top - 1); /* result is second op. */ 373 setobjs2s(L, top - 2, top - 1); /* result is second op. */
372 } 374 }
373 else { 375 else {
374 /* at least two non-empty string values; get as many as possible */ 376 /* at least two non-empty string values; get as many as possible */
375 size_t tl = tsvalue(top-1)->len; 377 size_t tl = vslen(top - 1);
376 char *buffer; 378 char *buffer;
377 int i; 379 int i;
378 /* collect total length */ 380 /* collect total length */
379 for (i = 1; i < total && tostring(L, top-i-1); i++) { 381 for (i = 1; i < total && tostring(L, top-i-1); i++) {
380 size_t l = tsvalue(top-i-1)->len; 382 size_t l = vslen(top - i - 1);
381 if (l >= (MAX_SIZE/sizeof(char)) - tl) 383 if (l >= (MAX_SIZE/sizeof(char)) - tl)
382 luaG_runerror(L, "string length overflow"); 384 luaG_runerror(L, "string length overflow");
383 tl += l; 385 tl += l;
@@ -386,7 +388,7 @@ void luaV_concat (lua_State *L, int total) {
386 tl = 0; 388 tl = 0;
387 n = i; 389 n = i;
388 do { /* copy all strings to buffer */ 390 do { /* copy all strings to buffer */
389 size_t l = tsvalue(top-i)->len; 391 size_t l = vslen(top - i);
390 memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); 392 memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
391 tl += l; 393 tl += l;
392 } while (--i > 0); 394 } while (--i > 0);
@@ -403,7 +405,7 @@ void luaV_concat (lua_State *L, int total) {
403*/ 405*/
404void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { 406void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
405 const TValue *tm; 407 const TValue *tm;
406 switch (ttnov(rb)) { 408 switch (ttype(rb)) {
407 case LUA_TTABLE: { 409 case LUA_TTABLE: {
408 Table *h = hvalue(rb); 410 Table *h = hvalue(rb);
409 tm = fasttm(L, h->metatable, TM_LEN); 411 tm = fasttm(L, h->metatable, TM_LEN);
@@ -411,8 +413,12 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
411 setivalue(ra, luaH_getn(h)); /* else primitive len */ 413 setivalue(ra, luaH_getn(h)); /* else primitive len */
412 return; 414 return;
413 } 415 }
414 case LUA_TSTRING: { 416 case LUA_TSHRSTR: {
415 setivalue(ra, tsvalue(rb)->len); 417 setivalue(ra, tsvalue(rb)->shrlen);
418 return;
419 }
420 case LUA_TLNGSTR: {
421 setivalue(ra, tsvalue(rb)->u.lnglen);
416 return; 422 return;
417 } 423 }
418 default: { /* try metamethod */ 424 default: { /* try metamethod */