** Main operation for concatenation: concat 'total' values in the stack, ** from 'L->top.p - total' up to 'L->top.p - 1'. */
| 682 | ** from 'L->top.p - total' up to 'L->top.p - 1'. |
| 683 | */ |
| 684 | void luaV_concat (lua_State *L, int total) { |
| 685 | if (total == 1) |
| 686 | return; /* "all" values already concatenated */ |
| 687 | do { |
| 688 | StkId top = L->top.p; |
| 689 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 690 | if (!(ttisstring(s2v(top - 2)) || cvt2str(s2v(top - 2))) || |
| 691 | !tostring(L, s2v(top - 1))) |
| 692 | luaT_tryconcatTM(L); /* may invalidate 'top' */ |
| 693 | else if (isemptystr(s2v(top - 1))) /* second operand is empty? */ |
| 694 | cast_void(tostring(L, s2v(top - 2))); /* result is first operand */ |
| 695 | else if (isemptystr(s2v(top - 2))) { /* first operand is empty string? */ |
| 696 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ |
| 697 | } |
| 698 | else { |
| 699 | /* at least two string values; get as many as possible */ |
| 700 | size_t tl = tsslen(tsvalue(s2v(top - 1))); /* total length */ |
| 701 | TString *ts; |
| 702 | /* collect total length and number of strings */ |
| 703 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
| 704 | size_t l = tsslen(tsvalue(s2v(top - n - 1))); |
| 705 | if (l_unlikely(l >= MAX_SIZE - sizeof(TString) - tl)) { |
| 706 | L->top.p = top - total; /* pop strings to avoid wasting stack */ |
| 707 | luaG_runerror(L, "string length overflow"); |
| 708 | } |
| 709 | tl += l; |
| 710 | } |
| 711 | if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ |
| 712 | char buff[LUAI_MAXSHORTLEN]; |
| 713 | copy2buff(top, n, buff); /* copy strings to buffer */ |
| 714 | ts = luaS_newlstr(L, buff, tl); |
| 715 | } |
| 716 | else { /* long string; copy strings directly to final result */ |
| 717 | ts = luaS_createlngstrobj(L, tl); |
| 718 | copy2buff(top, n, getlngstr(ts)); |
| 719 | } |
| 720 | setsvalue2s(L, top - n, ts); /* create result */ |
| 721 | } |
| 722 | total -= n - 1; /* got 'n' strings to create one new */ |
| 723 | L->top.p -= n - 1; /* popped 'n' strings and pushed one */ |
| 724 | } while (total > 1); /* repeat until only 1 result left */ |
| 725 | } |
| 726 | |
| 727 | |
| 728 | /* |
no test coverage detected