| 15109 | |
| 15110 | |
| 15111 | void luaV_concat (lua_State *L, int total, int last) { |
| 15112 | do { |
| 15113 | StkId top = L->base + last + 1; |
| 15114 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 15115 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { |
| 15116 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
| 15117 | luaG_concaterror(L, top-2, top-1); |
| 15118 | } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ |
| 15119 | (void)tostring(L, top - 2); /* result is first op (as string) */ |
| 15120 | else { |
| 15121 | /* at least two string values; get as many as possible */ |
| 15122 | size_t tl = tsvalue(top-1)->len; |
| 15123 | char *buffer; |
| 15124 | int i; |
| 15125 | /* collect total length */ |
| 15126 | for (n = 1; n < total && tostring(L, top-n-1); n++) { |
| 15127 | size_t l = tsvalue(top-n-1)->len; |
| 15128 | if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); |
| 15129 | tl += l; |
| 15130 | } |
| 15131 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
| 15132 | tl = 0; |
| 15133 | for (i=n; i>0; i--) { /* concat all strings */ |
| 15134 | size_t l = tsvalue(top-i)->len; |
| 15135 | memcpy(buffer+tl, svalue(top-i), l); |
| 15136 | tl += l; |
| 15137 | } |
| 15138 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); |
| 15139 | } |
| 15140 | total -= n-1; /* got `n' strings to create 1 new */ |
| 15141 | last -= n-1; |
| 15142 | } while (total > 1); /* repeat until only 1 result left */ |
| 15143 | } |
| 15144 | |
| 15145 | |
| 15146 | static void Arith (lua_State *L, StkId ra, const TValue *rb, |
no test coverage detected