** Main operation for concatenation: concat 'total' values in the stack, ** from 'L->top - total' up to 'L->top - 1'. */
| 518 | ** from 'L->top - total' up to 'L->top - 1'. |
| 519 | */ |
| 520 | void luaV_concat(lua_State *L, int total) { |
| 521 | lua_assert(total >= 2); |
| 522 | do { |
| 523 | StkId top = L->top; |
| 524 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 525 | if (!(ttisstring(top - 2) || cvt2str(top - 2)) || !tostring(L, top - 1)) |
| 526 | luaT_trybinTM(L, top - 2, top - 1, top - 2, TM_CONCAT); |
| 527 | else if (isemptystr(top - 1)) /* second operand is empty? */ |
| 528 | cast_void(tostring(L, top - 2)); /* result is first operand */ |
| 529 | else if (isemptystr(top - 2)) { /* first operand is an empty string? */ |
| 530 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ |
| 531 | } |
| 532 | else { |
| 533 | /* at least two non-empty string values; get as many as possible */ |
| 534 | size_t tl = vslen(top - 1); |
| 535 | TString *ts; |
| 536 | /* collect total length and number of strings */ |
| 537 | for (n = 1; n < total && tostring(L, top - n - 1); n++) { |
| 538 | size_t l = vslen(top - n - 1); |
| 539 | if (l >= (MAX_SIZE / sizeof(char)) - tl) |
| 540 | luaG_runerror(L, "string length overflow"); |
| 541 | tl += l; |
| 542 | } |
| 543 | if (tl <= LUAI_MAXSHORTLEN) { /* is result a short string? */ |
| 544 | char buff[LUAI_MAXSHORTLEN]; |
| 545 | copy2buff(top, n, buff); /* copy strings to buffer */ |
| 546 | ts = luaS_newlstr(L, buff, tl); |
| 547 | } |
| 548 | else { /* long string; copy strings directly to final result */ |
| 549 | ts = luaS_createlngstrobj(L, tl); |
| 550 | copy2buff(top, n, getstr(ts)); |
| 551 | } |
| 552 | setsvalue2s(L, top - n, ts); /* create result */ |
| 553 | } |
| 554 | total -= n - 1; /* got 'n' strings to create 1 new */ |
| 555 | L->top -= n - 1; /* popped 'n' strings and pushed one */ |
| 556 | } while (total > 1); /* repeat until only 1 result left */ |
| 557 | } |
| 558 | |
| 559 | |
| 560 | /* |
no test coverage detected