diff options
| -rw-r--r-- | lapi.c | 4 | ||||
| -rw-r--r-- | ldebug.c | 6 | ||||
| -rw-r--r-- | lgc.c | 8 | ||||
| -rw-r--r-- | lobject.c | 2 | ||||
| -rw-r--r-- | lobject.h | 18 | ||||
| -rw-r--r-- | lstate.c | 2 | ||||
| -rw-r--r-- | lstring.c | 11 | ||||
| -rw-r--r-- | lundump.c | 2 | ||||
| -rw-r--r-- | lvm.c | 17 |
9 files changed, 37 insertions, 33 deletions
| @@ -417,9 +417,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { | |||
| 417 | o = index2value(L, idx); /* previous call may reallocate the stack */ | 417 | o = index2value(L, idx); /* previous call may reallocate the stack */ |
| 418 | } | 418 | } |
| 419 | if (len != NULL) | 419 | if (len != NULL) |
| 420 | *len = vslen(o); | 420 | *len = tsslen(tsvalue(o)); |
| 421 | lua_unlock(L); | 421 | lua_unlock(L); |
| 422 | return svalue(o); | 422 | return getstr(tsvalue(o)); |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | 425 | ||
| @@ -426,7 +426,7 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, | |||
| 426 | */ | 426 | */ |
| 427 | static void kname (const Proto *p, int c, const char **name) { | 427 | static void kname (const Proto *p, int c, const char **name) { |
| 428 | TValue *kvalue = &p->k[c]; | 428 | TValue *kvalue = &p->k[c]; |
| 429 | *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?"; | 429 | *name = (ttisstring(kvalue)) ? getstr(tsvalue(kvalue)) : "?"; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | 432 | ||
| @@ -569,7 +569,7 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, | |||
| 569 | int b = (op == OP_LOADK) ? GETARG_Bx(i) | 569 | int b = (op == OP_LOADK) ? GETARG_Bx(i) |
| 570 | : GETARG_Ax(p->code[pc + 1]); | 570 | : GETARG_Ax(p->code[pc + 1]); |
| 571 | if (ttisstring(&p->k[b])) { | 571 | if (ttisstring(&p->k[b])) { |
| 572 | *name = svalue(&p->k[b]); | 572 | *name = getstr(tsvalue(&p->k[b])); |
| 573 | return "constant"; | 573 | return "constant"; |
| 574 | } | 574 | } |
| 575 | break; | 575 | break; |
| @@ -627,7 +627,7 @@ static const char *funcnamefromcode (lua_State *L, const Proto *p, | |||
| 627 | default: | 627 | default: |
| 628 | return NULL; /* cannot find a reasonable name */ | 628 | return NULL; /* cannot find a reasonable name */ |
| 629 | } | 629 | } |
| 630 | *name = getstr(G(L)->tmname[tm]) + 2; | 630 | *name = getshrstr(G(L)->tmname[tm]) + 2; |
| 631 | return "metamethod"; | 631 | return "metamethod"; |
| 632 | } | 632 | } |
| 633 | 633 | ||
| @@ -542,10 +542,12 @@ static void traversestrongtable (global_State *g, Table *h) { | |||
| 542 | static lu_mem traversetable (global_State *g, Table *h) { | 542 | static lu_mem traversetable (global_State *g, Table *h) { |
| 543 | const char *weakkey, *weakvalue; | 543 | const char *weakkey, *weakvalue; |
| 544 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); | 544 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); |
| 545 | TString *smode; | ||
| 545 | markobjectN(g, h->metatable); | 546 | markobjectN(g, h->metatable); |
| 546 | if (mode && ttisstring(mode) && /* is there a weak mode? */ | 547 | if (mode && ttisshrstring(mode) && /* is there a weak mode? */ |
| 547 | (cast_void(weakkey = strchr(svalue(mode), 'k')), | 548 | (cast_void(smode = tsvalue(mode)), |
| 548 | cast_void(weakvalue = strchr(svalue(mode), 'v')), | 549 | cast_void(weakkey = strchr(getshrstr(smode), 'k')), |
| 550 | cast_void(weakvalue = strchr(getshrstr(smode), 'v')), | ||
| 549 | (weakkey || weakvalue))) { /* is really weak? */ | 551 | (weakkey || weakvalue))) { /* is really weak? */ |
| 550 | if (!weakkey) /* strong keys? */ | 552 | if (!weakkey) /* strong keys? */ |
| 551 | traverseweakvalue(g, h); | 553 | traverseweakvalue(g, h); |
| @@ -542,7 +542,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | |||
| 542 | addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ | 542 | addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ |
| 543 | clearbuff(&buff); /* empty buffer into the stack */ | 543 | clearbuff(&buff); /* empty buffer into the stack */ |
| 544 | lua_assert(buff.pushed == 1); | 544 | lua_assert(buff.pushed == 1); |
| 545 | return svalue(s2v(L->top.p - 1)); | 545 | return getstr(tsvalue(s2v(L->top.p - 1))); |
| 546 | } | 546 | } |
| 547 | 547 | ||
| 548 | 548 | ||
| @@ -386,7 +386,7 @@ typedef struct GCObject { | |||
| 386 | typedef struct TString { | 386 | typedef struct TString { |
| 387 | CommonHeader; | 387 | CommonHeader; |
| 388 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ | 388 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ |
| 389 | lu_byte shrlen; /* length for short strings */ | 389 | lu_byte shrlen; /* length for short strings, 0xFF for long strings */ |
| 390 | unsigned int hash; | 390 | unsigned int hash; |
| 391 | union { | 391 | union { |
| 392 | size_t lnglen; /* length for long strings */ | 392 | size_t lnglen; /* length for long strings */ |
| @@ -398,19 +398,17 @@ typedef struct TString { | |||
| 398 | 398 | ||
| 399 | 399 | ||
| 400 | /* | 400 | /* |
| 401 | ** Get the actual string (array of bytes) from a 'TString'. | 401 | ** Get the actual string (array of bytes) from a 'TString'. (Generic |
| 402 | ** version and specialized versions for long and short strings.) | ||
| 402 | */ | 403 | */ |
| 403 | #define getstr(ts) ((ts)->contents) | 404 | #define getstr(ts) ((ts)->contents) |
| 405 | #define getlngstr(ts) check_exp((ts)->shrlen == 0xFF, (ts)->contents) | ||
| 406 | #define getshrstr(ts) check_exp((ts)->shrlen != 0xFF, (ts)->contents) | ||
| 404 | 407 | ||
| 405 | 408 | ||
| 406 | /* get the actual string (array of bytes) from a Lua value */ | ||
| 407 | #define svalue(o) getstr(tsvalue(o)) | ||
| 408 | |||
| 409 | /* get string length from 'TString *s' */ | 409 | /* get string length from 'TString *s' */ |
| 410 | #define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen) | 410 | #define tsslen(s) \ |
| 411 | 411 | ((s)->shrlen != 0xFF ? (s)->shrlen : (s)->u.lnglen) | |
| 412 | /* get string length from 'TValue *o' */ | ||
| 413 | #define vslen(o) tsslen(tsvalue(o)) | ||
| 414 | 412 | ||
| 415 | /* }================================================================== */ | 413 | /* }================================================================== */ |
| 416 | 414 | ||
| @@ -433,7 +433,7 @@ void luaE_warning (lua_State *L, const char *msg, int tocont) { | |||
| 433 | void luaE_warnerror (lua_State *L, const char *where) { | 433 | void luaE_warnerror (lua_State *L, const char *where) { |
| 434 | TValue *errobj = s2v(L->top.p - 1); /* error object */ | 434 | TValue *errobj = s2v(L->top.p - 1); /* error object */ |
| 435 | const char *msg = (ttisstring(errobj)) | 435 | const char *msg = (ttisstring(errobj)) |
| 436 | ? svalue(errobj) | 436 | ? getstr(tsvalue(errobj)) |
| 437 | : "error object is not a string"; | 437 | : "error object is not a string"; |
| 438 | /* produce warning "error in %s (%s)" (where, msg) */ | 438 | /* produce warning "error in %s (%s)" (where, msg) */ |
| 439 | luaE_warning(L, "error in ", 1); | 439 | luaE_warning(L, "error in ", 1); |
| @@ -36,7 +36,7 @@ int luaS_eqlngstr (TString *a, TString *b) { | |||
| 36 | lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); | 36 | lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); |
| 37 | return (a == b) || /* same instance or... */ | 37 | return (a == b) || /* same instance or... */ |
| 38 | ((len == b->u.lnglen) && /* equal length and ... */ | 38 | ((len == b->u.lnglen) && /* equal length and ... */ |
| 39 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ | 39 | (memcmp(getlngstr(a), getlngstr(b), len) == 0)); /* equal contents */ |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | 42 | ||
| @@ -52,7 +52,7 @@ unsigned int luaS_hashlongstr (TString *ts) { | |||
| 52 | lua_assert(ts->tt == LUA_VLNGSTR); | 52 | lua_assert(ts->tt == LUA_VLNGSTR); |
| 53 | if (ts->extra == 0) { /* no hash? */ | 53 | if (ts->extra == 0) { /* no hash? */ |
| 54 | size_t len = ts->u.lnglen; | 54 | size_t len = ts->u.lnglen; |
| 55 | ts->hash = luaS_hash(getstr(ts), len, ts->hash); | 55 | ts->hash = luaS_hash(getlngstr(ts), len, ts->hash); |
| 56 | ts->extra = 1; /* now it has its hash */ | 56 | ts->extra = 1; /* now it has its hash */ |
| 57 | } | 57 | } |
| 58 | return ts->hash; | 58 | return ts->hash; |
| @@ -157,6 +157,7 @@ static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { | |||
| 157 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { | 157 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { |
| 158 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); | 158 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); |
| 159 | ts->u.lnglen = l; | 159 | ts->u.lnglen = l; |
| 160 | ts->shrlen = 0xFF; /* signals that it is a long string */ | ||
| 160 | return ts; | 161 | return ts; |
| 161 | } | 162 | } |
| 162 | 163 | ||
| @@ -193,7 +194,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
| 193 | TString **list = &tb->hash[lmod(h, tb->size)]; | 194 | TString **list = &tb->hash[lmod(h, tb->size)]; |
| 194 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ | 195 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ |
| 195 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { | 196 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { |
| 196 | if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | 197 | if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { |
| 197 | /* found! */ | 198 | /* found! */ |
| 198 | if (isdead(g, ts)) /* dead (but not collected yet)? */ | 199 | if (isdead(g, ts)) /* dead (but not collected yet)? */ |
| 199 | changewhite(ts); /* resurrect it */ | 200 | changewhite(ts); /* resurrect it */ |
| @@ -206,7 +207,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
| 206 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ | 207 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ |
| 207 | } | 208 | } |
| 208 | ts = createstrobj(L, l, LUA_VSHRSTR, h); | 209 | ts = createstrobj(L, l, LUA_VSHRSTR, h); |
| 209 | memcpy(getstr(ts), str, l * sizeof(char)); | 210 | memcpy(getshrstr(ts), str, l * sizeof(char)); |
| 210 | ts->shrlen = cast_byte(l); | 211 | ts->shrlen = cast_byte(l); |
| 211 | ts->u.hnext = *list; | 212 | ts->u.hnext = *list; |
| 212 | *list = ts; | 213 | *list = ts; |
| @@ -226,7 +227,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
| 226 | if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) | 227 | if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) |
| 227 | luaM_toobig(L); | 228 | luaM_toobig(L); |
| 228 | ts = luaS_createlngstrobj(L, l); | 229 | ts = luaS_createlngstrobj(L, l); |
| 229 | memcpy(getstr(ts), str, l * sizeof(char)); | 230 | memcpy(getlngstr(ts), str, l * sizeof(char)); |
| 230 | return ts; | 231 | return ts; |
| 231 | } | 232 | } |
| 232 | } | 233 | } |
| @@ -122,7 +122,7 @@ static TString *loadStringN (LoadState *S, Proto *p) { | |||
| 122 | ts = luaS_createlngstrobj(L, size); /* create string */ | 122 | ts = luaS_createlngstrobj(L, size); /* create string */ |
| 123 | setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ | 123 | setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ |
| 124 | luaD_inctop(L); | 124 | luaD_inctop(L); |
| 125 | loadVector(S, getstr(ts), size); /* load directly in final place */ | 125 | loadVector(S, getlngstr(ts), size); /* load directly in final place */ |
| 126 | L->top.p--; /* pop string */ | 126 | L->top.p--; /* pop string */ |
| 127 | } | 127 | } |
| 128 | luaC_objbarrier(L, p, ts); | 128 | luaC_objbarrier(L, p, ts); |
| @@ -91,8 +91,10 @@ static int l_strton (const TValue *obj, TValue *result) { | |||
| 91 | lua_assert(obj != result); | 91 | lua_assert(obj != result); |
| 92 | if (!cvt2num(obj)) /* is object not a string? */ | 92 | if (!cvt2num(obj)) /* is object not a string? */ |
| 93 | return 0; | 93 | return 0; |
| 94 | else | 94 | else { |
| 95 | return (luaO_str2num(svalue(obj), result) == vslen(obj) + 1); | 95 | TString *st = tsvalue(obj); |
| 96 | return (luaO_str2num(getstr(st), result) == tsslen(st) + 1); | ||
| 97 | } | ||
| 96 | } | 98 | } |
| 97 | 99 | ||
| 98 | 100 | ||
| @@ -626,8 +628,9 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
| 626 | static void copy2buff (StkId top, int n, char *buff) { | 628 | static void copy2buff (StkId top, int n, char *buff) { |
| 627 | size_t tl = 0; /* size already copied */ | 629 | size_t tl = 0; /* size already copied */ |
| 628 | do { | 630 | do { |
| 629 | size_t l = vslen(s2v(top - n)); /* length of string being copied */ | 631 | TString *st = tsvalue(s2v(top - n)); |
| 630 | memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char)); | 632 | size_t l = tsslen(st); /* length of string being copied */ |
| 633 | memcpy(buff + tl, getstr(st), l * sizeof(char)); | ||
| 631 | tl += l; | 634 | tl += l; |
| 632 | } while (--n > 0); | 635 | } while (--n > 0); |
| 633 | } | 636 | } |
| @@ -653,11 +656,11 @@ void luaV_concat (lua_State *L, int total) { | |||
| 653 | } | 656 | } |
| 654 | else { | 657 | else { |
| 655 | /* at least two non-empty string values; get as many as possible */ | 658 | /* at least two non-empty string values; get as many as possible */ |
| 656 | size_t tl = vslen(s2v(top - 1)); | 659 | size_t tl = tsslen(tsvalue(s2v(top - 1))); |
| 657 | TString *ts; | 660 | TString *ts; |
| 658 | /* collect total length and number of strings */ | 661 | /* collect total length and number of strings */ |
| 659 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | 662 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
| 660 | size_t l = vslen(s2v(top - n - 1)); | 663 | size_t l = tsslen(tsvalue(s2v(top - n - 1))); |
| 661 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { | 664 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { |
| 662 | L->top.p = top - total; /* pop strings to avoid wasting stack */ | 665 | L->top.p = top - total; /* pop strings to avoid wasting stack */ |
| 663 | luaG_runerror(L, "string length overflow"); | 666 | luaG_runerror(L, "string length overflow"); |
| @@ -671,7 +674,7 @@ void luaV_concat (lua_State *L, int total) { | |||
| 671 | } | 674 | } |
| 672 | else { /* long string; copy strings directly to final result */ | 675 | else { /* long string; copy strings directly to final result */ |
| 673 | ts = luaS_createlngstrobj(L, tl); | 676 | ts = luaS_createlngstrobj(L, tl); |
| 674 | copy2buff(top, n, getstr(ts)); | 677 | copy2buff(top, n, getlngstr(ts)); |
| 675 | } | 678 | } |
| 676 | setsvalue2s(L, top - n, ts); /* create result */ | 679 | setsvalue2s(L, top - n, ts); /* create result */ |
| 677 | } | 680 | } |
