diff options
| -rw-r--r-- | lgc.c | 6 | ||||
| -rw-r--r-- | ltm.c | 2 | ||||
| -rw-r--r-- | lvm.c | 9 | ||||
| -rw-r--r-- | testes/strings.lua | 17 |
4 files changed, 28 insertions, 6 deletions
| @@ -594,10 +594,10 @@ static void traversestrongtable (global_State *g, Table *h) { | |||
| 594 | */ | 594 | */ |
| 595 | static int getmode (global_State *g, Table *h) { | 595 | static int getmode (global_State *g, Table *h) { |
| 596 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); | 596 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); |
| 597 | if (mode == NULL || !ttisshrstring(mode)) | 597 | if (mode == NULL || !ttisstring(mode)) |
| 598 | return 0; /* ignore non-(short)string modes */ | 598 | return 0; /* ignore non-string modes */ |
| 599 | else { | 599 | else { |
| 600 | const char *smode = getshrstr(tsvalue(mode)); | 600 | const char *smode = getstr(tsvalue(mode)); |
| 601 | const char *weakkey = strchr(smode, 'k'); | 601 | const char *weakkey = strchr(smode, 'k'); |
| 602 | const char *weakvalue = strchr(smode, 'v'); | 602 | const char *weakvalue = strchr(smode, 'v'); |
| 603 | return ((weakkey != NULL) << 1) | (weakvalue != NULL); | 603 | return ((weakkey != NULL) << 1) | (weakvalue != NULL); |
| @@ -287,7 +287,7 @@ void luaT_getvararg (CallInfo *ci, StkId ra, TValue *rc) { | |||
| 287 | return; | 287 | return; |
| 288 | } | 288 | } |
| 289 | } | 289 | } |
| 290 | else if (ttisshrstring(rc)) { /* short-string value? */ | 290 | else if (ttisstring(rc)) { /* string value? */ |
| 291 | size_t len; | 291 | size_t len; |
| 292 | const char *s = getlstr(tsvalue(rc), len); | 292 | const char *s = getlstr(tsvalue(rc), len); |
| 293 | if (len == 1 && s[0] == 'n') { /* key is "n"? */ | 293 | if (len == 1 && s[0] == 'n') { /* key is "n"? */ |
| @@ -657,6 +657,11 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
| 657 | #define tostring(L,o) \ | 657 | #define tostring(L,o) \ |
| 658 | (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) | 658 | (ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1))) |
| 659 | 659 | ||
| 660 | /* | ||
| 661 | ** Check whether object is a short empty string to optimize concatenation. | ||
| 662 | ** (External strings can be empty too; they will be concatenated like | ||
| 663 | ** non-empty ones.) | ||
| 664 | */ | ||
| 660 | #define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) | 665 | #define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0) |
| 661 | 666 | ||
| 662 | /* copy strings in stack from top - n up to top - 1 to buffer */ | 667 | /* copy strings in stack from top - n up to top - 1 to buffer */ |
| @@ -691,8 +696,8 @@ void luaV_concat (lua_State *L, int total) { | |||
| 691 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ | 696 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ |
| 692 | } | 697 | } |
| 693 | else { | 698 | else { |
| 694 | /* at least two non-empty string values; get as many as possible */ | 699 | /* at least two string values; get as many as possible */ |
| 695 | size_t tl = tsslen(tsvalue(s2v(top - 1))); | 700 | size_t tl = tsslen(tsvalue(s2v(top - 1))); /* total length */ |
| 696 | TString *ts; | 701 | TString *ts; |
| 697 | /* collect total length and number of strings */ | 702 | /* collect total length and number of strings */ |
| 698 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | 703 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
diff --git a/testes/strings.lua b/testes/strings.lua index 46912d43..84ff1154 100644 --- a/testes/strings.lua +++ b/testes/strings.lua | |||
| @@ -540,6 +540,23 @@ else | |||
| 540 | assert(y == x) | 540 | assert(y == x) |
| 541 | local z = T.externstr(x) -- external allocated long string | 541 | local z = T.externstr(x) -- external allocated long string |
| 542 | assert(z == y) | 542 | assert(z == y) |
| 543 | |||
| 544 | local e = T.externstr("") -- empty external string | ||
| 545 | assert(e .. "x" == "x" and "x" .. e == "x") | ||
| 546 | assert(e .. e == "" and #e == 0) | ||
| 547 | |||
| 548 | -- external string as the "n" key in vararg table | ||
| 549 | local n = T.externstr("n") | ||
| 550 | local n0 = T.externstr("n\0") | ||
| 551 | local function aux (...t) assert(t[n0] == nil); return t[n] end | ||
| 552 | assert(aux(10, 20, 30) == 3) | ||
| 553 | |||
| 554 | -- external string as mode in weak table | ||
| 555 | local t = setmetatable({}, {__mode = T.externstr("kv")}) | ||
| 556 | t[{}] = {} | ||
| 557 | assert(next(t)) | ||
| 558 | collectgarbage() | ||
| 559 | assert(next(t) == nil) | ||
| 543 | end | 560 | end |
| 544 | 561 | ||
| 545 | print('OK') | 562 | print('OK') |
